From d792baf9f7220a374788b35789335a7ae2e62369 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 24 Jun 2015 21:14:55 -0400 Subject: MAINT-5232: Introduce inter-LLSingleton dependency tracking. Introduce LLSingleton::cleanupSingleton() canonical method as the place to put any subclass cleanup logic that might take nontrivial realtime or throw an exception. Neither is appropriate in a destructor. Track all extant LLSingleton subclass instances on a master list, which permits adding LLSingletonBase::cleanupAll() and deleteAll() methods. Also notice when any LLSingleton subclass constructor (or initSingleton() method) calls instance() or getInstance() for another LLSingleton, and capture that other LLSingleton instance as a dependency of the first. This permits cleanupAll() and deleteAll() to perform a dependency sort on the master list, thus cleaning up (or deleting) leaf LLSingletons AFTER the LLSingletons that depend on them. Make C++ runtime's final static destructor call LLSingletonBase::deleteAll() instead of deleting individual LLSingleton instances in arbitrary order. Eliminate "llerror.h" from llsingleton.h, a longstanding TODO. --- indra/llcommon/llsingleton.cpp | 290 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 289 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 9b49e52377..204c0d24d0 100755 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -25,7 +25,295 @@ */ #include "linden_common.h" - #include "llsingleton.h" +#include "llerror.h" +#include "lldependencies.h" +#include +#include +#include +#include + +// Our master list of all LLSingletons is itself an LLSingleton. We used to +// store it in a function-local static, but that could get destroyed before +// the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to +// remove itself from the master list. Since the whole point of this master +// list is to help track inter-LLSingleton dependencies, and since we have +// this implicit dependency from every LLSingleton to the master list, make it +// an LLSingleton. +class LLSingletonBase::MasterList: + public LLSingleton +{ +private: + friend class LLSingleton; + +public: + // No need to make this private with accessors; nobody outside this source + // file can see it. + LLSingletonBase::list_t mList; +}; + +//static +LLSingletonBase::list_t& LLSingletonBase::get_master() +{ + return LLSingletonBase::MasterList::instance().mList; +} + +void LLSingletonBase::add_master() +{ + // As each new LLSingleton is constructed, add to the master list. + get_master().push_back(this); +} + +void LLSingletonBase::remove_master() +{ + // When an LLSingleton is destroyed, remove from master list. + // add_master() used to capture the iterator to the newly-added list item + // so we could directly erase() it from the master list. Unfortunately + // that runs afoul of destruction-dependency order problems. So search the + // master list, and remove this item IF FOUND. We have few enough + // LLSingletons, and they are so rarely destroyed (once per run), that the + // cost of a linear search should not be an issue. + get_master().remove(this); +} + +// Wrapping our initializing list in a static method ensures that it will be +// constructed on demand. This list doesn't also need to be in an LLSingleton +// because (a) it should be empty by program shutdown and (b) none of our +// destructors reference it. +//static +LLSingletonBase::list_t& LLSingletonBase::get_initializing() +{ + static list_t sList; + return sList; +} + +LLSingletonBase::LLSingletonBase(): + mCleaned(false), + mDeleteSingleton(NULL) +{ + // Make this the currently-initializing LLSingleton. + push_initializing(); +} + +LLSingletonBase::~LLSingletonBase() {} + +void LLSingletonBase::push_initializing() +{ + get_initializing().push_back(this); +} + +void LLSingletonBase::pop_initializing() +{ + list_t& list(get_initializing()); + if (list.empty()) + { + LL_ERRS() << "Underflow in stack of currently-initializing LLSingletons at " + << typeid(*this).name() << "::getInstance()" << LL_ENDL; + } + if (list.back() != this) + { + LL_ERRS() << "Push/pop mismatch in stack of currently-initializing LLSingletons: " + << typeid(*this).name() << "::getInstance() trying to pop " + << typeid(*list.back()).name() << LL_ENDL; + } + // Here we're sure that list.back() == this. Whew, pop it. + list.pop_back(); +} + +void LLSingletonBase::capture_dependency() +{ + // Did this getInstance() call come from another LLSingleton, or from + // vanilla application code? Note that although this is a nontrivial + // method, the vast majority of its calls arrive here with initializing + // empty(). + list_t& initializing(get_initializing()); + if (! initializing.empty()) + { + // getInstance() is being called by some other LLSingleton. But -- is + // this a circularity? That is, does 'this' already appear in the + // initializing stack? + // For what it's worth, normally 'initializing' should contain very + // few elements. + list_t::const_iterator found = + std::find(initializing.begin(), initializing.end(), this); + if (found != initializing.end()) + { + // Report the circularity. Requiring the coder to dig through the + // logic to diagnose exactly how we got here is less than helpful. + std::ostringstream out; + for ( ; found != initializing.end(); ++found) + { + // 'found' is an iterator; *found is an LLSingletonBase*; **found + // is the actual LLSingletonBase instance. + out << typeid(**found).name() << " -> "; + } + // DEBUGGING: Initially, make this crump. We want to know how bad + // the problem is before we add it to the long, sad list of + // ominous warnings that everyone always ignores. + LL_ERRS() << "LLSingleton circularity: " << out.str() + << typeid(*this).name() << LL_ENDL; + } + else + { + // Here 'this' is NOT already in the 'initializing' stack. Great! + // Record the dependency. + // initializing.back() is the LLSingletonBase* currently being + // initialized. Store 'this' in its mDepends set. + initializing.back()->mDepends.insert(this); + } + } +} + +//static +LLSingletonBase::vec_t LLSingletonBase::dep_sort() +{ + // While it would theoretically be possible to maintain a static + // SingletonDeps through the life of the program, dynamically adding and + // removing LLSingletons as they are created and destroyed, in practice + // it's less messy to construct it on demand. The overhead of doing so + // should happen basically twice: once for cleanupAll(), once for + // deleteAll(). + typedef LLDependencies SingletonDeps; + SingletonDeps sdeps; + list_t& master(get_master()); + BOOST_FOREACH(LLSingletonBase* sp, master) + { + // Build the SingletonDeps structure by adding, for each + // LLSingletonBase* sp in the master list, sp itself. It has no + // associated value type in our SingletonDeps, hence the 0. We don't + // record the LLSingletons it must follow; rather, we record the ones + // it must precede. Copy its mDepends to a KeyList to express that. + sdeps.add(sp, 0, + SingletonDeps::KeyList(), + SingletonDeps::KeyList(sp->mDepends.begin(), sp->mDepends.end())); + } + vec_t ret; + ret.reserve(master.size()); + // We should be able to effect this with a transform_iterator that + // extracts just the first (key) element from each sorted_iterator, then + // uses vec_t's range constructor... but frankly this is more + // straightforward, as long as we remember the above reserve() call! + BOOST_FOREACH(SingletonDeps::sorted_iterator::value_type pair, sdeps.sort()) + { + ret.push_back(pair.first); + } + // The master list is not itself pushed onto the master list. Add it as + // the very last entry -- it is the LLSingleton on which ALL others + // depend! -- so our caller will process it. + ret.push_back(MasterList::getInstance()); + return ret; +} + +//static +void LLSingletonBase::cleanupAll() +{ + // It's essential to traverse these in dependency order. + BOOST_FOREACH(LLSingletonBase* sp, dep_sort()) + { + // Call cleanupSingleton() only if we haven't already done so for this + // instance. + if (! sp->mCleaned) + { + sp->mCleaned = true; + + try + { + sp->cleanupSingleton(); + } + catch (const std::exception& e) + { + LL_WARNS() << "Exception in " << typeid(*sp).name() + << "::cleanupSingleton(): " << e.what() << LL_ENDL; + } + catch (...) + { + LL_WARNS() << "Unknown exception in " << typeid(*sp).name() + << "::cleanupSingleton()" << LL_ENDL; + } + } + } +} + +//static +void LLSingletonBase::deleteAll() +{ + // It's essential to traverse these in dependency order. + BOOST_FOREACH(LLSingletonBase* sp, dep_sort()) + { + // Capture the class name first: in case of exception, don't count on + // being able to extract it later. + const char* name = typeid(*sp).name(); + try + { + // Call static method through instance function pointer. + if (! sp->mDeleteSingleton) + { + // This Should Not Happen... but carry on. + LL_WARNS() << name << "::mDeleteSingleton not initialized!" << LL_ENDL; + } + else + { + // properly initialized: call it. + // From this point on, DO NOT DEREFERENCE sp! + sp->mDeleteSingleton(); + } + } + catch (const std::exception& e) + { + LL_WARNS() << "Exception in " << name + << "::deleteSingleton(): " << e.what() << LL_ENDL; + } + catch (...) + { + LL_WARNS() << "Unknown exception in " << name + << "::deleteSingleton()" << LL_ENDL; + } + } +} + +/*------------------------ Final cleanup management ------------------------*/ +class LLSingletonBase::MasterRefcount +{ +public: + // store a POD int so it will be statically initialized to 0 + int refcount; +}; +static LLSingletonBase::MasterRefcount sMasterRefcount; + +LLSingletonBase::ref_ptr_t LLSingletonBase::get_master_refcount() +{ + // Calling this method constructs a new ref_ptr_t, which implicitly calls + // intrusive_ptr_add_ref(MasterRefcount*). + return &sMasterRefcount; +} + +void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount* mrc) +{ + // Count outstanding SingletonLifetimeManager instances. + ++mrc->refcount; +} + +void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc) +{ + // Notice when each SingletonLifetimeManager instance is destroyed. + if (! --mrc->refcount) + { + // The last instance was destroyed. Time to kill any remaining + // LLSingletons -- but in dependency order. + LLSingletonBase::deleteAll(); + } +} + +/*---------------------------- Logging helpers -----------------------------*/ +//static +void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3) +{ + LL_ERRS() << p1 << p2 << p3 << LL_ENDL; +} +//static +void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3) +{ + LL_WARNS() << p1 << p2 << p3 << LL_ENDL; +} -- cgit v1.3 From 0ea1b2a164e0d985c80c8a1afea4b31670efc907 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 25 Jun 2015 16:04:01 -0400 Subject: MAINT-5232: Try to avoid circularity between LLError and LLSingleton. Part of LLError's logging infrastructure is implemented with an LLSingleton. Therefore, attempts to log from within LLSingleton machinery could potentially go south if LLError's LLSingleton is not yet initialized. Introduce LLError::is_available() in llerrorcontrol.h and llerror.cpp. Make LLSingletonBase::logwarns() and logerrs() consult LLError::is_available() before attempting to use LL_WARNS or LL_ERRS, respectively. Moreover, make all LLSingleton internal logging use logwarns() and logerrs() instead of directly engaging LL_ERRS or LL_WARNS. --- indra/llcommon/llerror.cpp | 5 ++++ indra/llcommon/llerrorcontrol.h | 5 ++++ indra/llcommon/llsingleton.cpp | 64 ++++++++++++++++++++++++++++------------- indra/llcommon/llsingleton.h | 6 ++-- 4 files changed, 58 insertions(+), 22 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 2100989316..54524bbe8e 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -402,6 +402,11 @@ namespace namespace LLError { + bool is_available() + { + return Globals::instanceExists(); + } + class SettingsConfig : public LLRefCount { friend class Settings; diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 56ac52e5de..56e84f7172 100755 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -189,6 +189,11 @@ namespace LLError LL_COMMON_API std::string abbreviateFile(const std::string& filePath); LL_COMMON_API int shouldLogCallCount(); + + // Check whether Globals exists. This should only be used by LLSingleton + // infrastructure to avoid trying to log when our internal LLSingleton is + // unavailable -- circularity ensues. + LL_COMMON_API bool is_available(); }; #endif // LL_LLERRORCONTROL_H diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 204c0d24d0..a3edf925ad 100755 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -28,9 +28,11 @@ #include "llsingleton.h" #include "llerror.h" +#include "llerrorcontrol.h" // LLError::is_available() #include "lldependencies.h" #include #include +#include // std::cerr in dire emergency #include #include @@ -108,14 +110,14 @@ void LLSingletonBase::pop_initializing() list_t& list(get_initializing()); if (list.empty()) { - LL_ERRS() << "Underflow in stack of currently-initializing LLSingletons at " - << typeid(*this).name() << "::getInstance()" << LL_ENDL; + logerrs("Underflow in stack of currently-initializing LLSingletons at ", + typeid(*this).name(), "::getInstance()"); } if (list.back() != this) { - LL_ERRS() << "Push/pop mismatch in stack of currently-initializing LLSingletons: " - << typeid(*this).name() << "::getInstance() trying to pop " - << typeid(*list.back()).name() << LL_ENDL; + logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", + typeid(*this).name(), "::getInstance() trying to pop ", + typeid(*list.back()).name()); } // Here we're sure that list.back() == this. Whew, pop it. list.pop_back(); @@ -151,8 +153,8 @@ void LLSingletonBase::capture_dependency() // DEBUGGING: Initially, make this crump. We want to know how bad // the problem is before we add it to the long, sad list of // ominous warnings that everyone always ignores. - LL_ERRS() << "LLSingleton circularity: " << out.str() - << typeid(*this).name() << LL_ENDL; + logerrs("LLSingleton circularity: ", out.str().c_str(), + typeid(*this).name()); } else { @@ -223,13 +225,13 @@ void LLSingletonBase::cleanupAll() } catch (const std::exception& e) { - LL_WARNS() << "Exception in " << typeid(*sp).name() - << "::cleanupSingleton(): " << e.what() << LL_ENDL; + logwarns("Exception in ", typeid(*sp).name(), + "::cleanupSingleton(): ", e.what()); } catch (...) { - LL_WARNS() << "Unknown exception in " << typeid(*sp).name() - << "::cleanupSingleton()" << LL_ENDL; + logwarns("Unknown exception in ", typeid(*sp).name(), + "::cleanupSingleton()"); } } } @@ -250,7 +252,7 @@ void LLSingletonBase::deleteAll() if (! sp->mDeleteSingleton) { // This Should Not Happen... but carry on. - LL_WARNS() << name << "::mDeleteSingleton not initialized!" << LL_ENDL; + logwarns(name, "::mDeleteSingleton not initialized!"); } else { @@ -261,13 +263,11 @@ void LLSingletonBase::deleteAll() } catch (const std::exception& e) { - LL_WARNS() << "Exception in " << name - << "::deleteSingleton(): " << e.what() << LL_ENDL; + logwarns("Exception in ", name, "::deleteSingleton(): ", e.what()); } catch (...) { - LL_WARNS() << "Unknown exception in " << name - << "::deleteSingleton()" << LL_ENDL; + logwarns("Unknown exception in ", name, "::deleteSingleton()"); } } } @@ -307,13 +307,37 @@ void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc) /*---------------------------- Logging helpers -----------------------------*/ //static -void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3) +void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4) { - LL_ERRS() << p1 << p2 << p3 << LL_ENDL; + // Check LLError::is_available() because some of LLError's infrastructure + // is itself an LLSingleton. If that LLSingleton has not yet been + // initialized, trying to log will engage LLSingleton machinery... and + // around and around we go. + if (LLError::is_available()) + { + LL_ERRS() << p1 << p2 << p3 << p4 << LL_ENDL; + } + else + { + // Caller may be a test program, or something else whose stderr is + // visible to the user. + std::cerr << p1 << p2 << p3 << p4 << std::endl; + // The other important side effect of LL_ERRS() is + // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG) + LLError::crashAndLoop(std::string()); + } } //static -void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3) +void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4) { - LL_WARNS() << p1 << p2 << p3 << LL_ENDL; + // See logerrs() remarks about is_available(). + if (LLError::is_available()) + { + LL_WARNS() << p1 << p2 << p3 << p4 << LL_ENDL; + } + else + { + std::cerr << p1 << p2 << p3 << p4 << std::endl; + } } diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 7706ed53f2..d66ea33c0c 100755 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -90,9 +90,11 @@ protected: void capture_dependency(); // delegate LL_ERRS() logging to llsingleton.cpp - static void logerrs(const char* p1, const char* p2="", const char* p3=""); + static void logerrs(const char* p1, const char* p2="", + const char* p3="", const char* p4=""); // delegate LL_WARNS() logging to llsingleton.cpp - static void logwarns(const char* p1, const char* p2="", const char* p3=""); + static void logwarns(const char* p1, const char* p2="", + const char* p3="", const char* p4=""); // obtain canonical ref_ptr_t static ref_ptr_t get_master_refcount(); -- cgit v1.3 From 687efd84eabc524e339e61458b0cbf53f9a38f8a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 26 Jun 2015 13:03:59 -0400 Subject: MAINT-5232: Loosen LLSingleton circularity constraints slightly. LLSingleton explicitly supports circular dependencies: initialization performed during an LLSingleton subclass's initSingleton() method may recursively call that same subclass's getInstance() method. On the other hand, circularity from a subclass constructor cannot be permitted, else getInstance() would have to return a partially-constructed object. Our dependency tracking circularity check initially forbade both. Loosen it to permit references from within initSingleton(). --- indra/llcommon/llsingleton.cpp | 19 +++++++++++++------ indra/llcommon/llsingleton.h | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 17 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index a3edf925ad..2813814ae1 100755 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -123,7 +123,7 @@ void LLSingletonBase::pop_initializing() list.pop_back(); } -void LLSingletonBase::capture_dependency() +void LLSingletonBase::capture_dependency(EInitState initState) { // Did this getInstance() call come from another LLSingleton, or from // vanilla application code? Note that although this is a nontrivial @@ -150,11 +150,18 @@ void LLSingletonBase::capture_dependency() // is the actual LLSingletonBase instance. out << typeid(**found).name() << " -> "; } - // DEBUGGING: Initially, make this crump. We want to know how bad - // the problem is before we add it to the long, sad list of - // ominous warnings that everyone always ignores. - logerrs("LLSingleton circularity: ", out.str().c_str(), - typeid(*this).name()); + // We promise to capture dependencies from both the constructor + // and the initSingleton() method, so an LLSingleton's instance + // pointer is on the initializing list during both. Now that we've + // detected circularity, though, we must distinguish the two. If + // the recursive call is from the constructor, we CAN'T honor it: + // otherwise we'd be returning a pointer to a partially- + // constructed object! But from initSingleton() is okay: that + // method exists specifically to support circularity. + // Decide which log helper to call based on initState. They have + // identical signatures. + ((initState == CONSTRUCTING)? logerrs : logwarns) + ("LLSingleton circularity: ", out.str().c_str(), typeid(*this).name(), ""); } else { diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 25bdba0a0d..a82101c367 100755 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -58,6 +58,15 @@ private: set_t mDepends; protected: + typedef enum e_init_state + { + UNINITIALIZED = 0, // must be default-initialized state + CONSTRUCTING, + INITIALIZING, + INITIALIZED, + DELETED + } EInitState; + // Base-class constructor should only be invoked by the DERIVED_TYPE // constructor. LLSingletonBase(); @@ -87,7 +96,7 @@ protected: void pop_initializing(); // If a given call to B::getInstance() happens during either A::A() or // A::initSingleton(), record that A directly depends on B. - void capture_dependency(); + void capture_dependency(EInitState); // delegate LL_ERRS() logging to llsingleton.cpp static void logerrs(const char* p1, const char* p2="", @@ -232,15 +241,6 @@ template class LLSingleton : public LLSingletonBase { private: - typedef enum e_init_state - { - UNINITIALIZED = 0, // must be default-initialized state - CONSTRUCTING, - INITIALIZING, - INITIALIZED, - DELETED - } EInitState; - static DERIVED_TYPE* constructSingleton() { return new DERIVED_TYPE(); @@ -377,7 +377,7 @@ public: // an LLSingleton that directly depends on DERIVED_TYPE. If this call // came from another LLSingleton, rather than from vanilla application // code, record the dependency. - sData.mInstance->capture_dependency(); + sData.mInstance->capture_dependency(sData.mInitState); return sData.mInstance; } -- cgit v1.3 From 8fee1565eb310081a7f3e26237ddd776c5a9aaaa Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 26 Jun 2015 15:28:57 -0400 Subject: MAINT-5232: Use LLError::Log::demangle() to log LLSingleton classes. --- indra/llcommon/llsingleton.cpp | 28 +++++++++++++++++----------- indra/llcommon/llsingleton.h | 10 +++++++--- 2 files changed, 24 insertions(+), 14 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 2813814ae1..b78110296f 100755 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -111,13 +111,13 @@ void LLSingletonBase::pop_initializing() if (list.empty()) { logerrs("Underflow in stack of currently-initializing LLSingletons at ", - typeid(*this).name(), "::getInstance()"); + demangle(typeid(*this).name()).c_str(), "::getInstance()"); } if (list.back() != this) { logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", - typeid(*this).name(), "::getInstance() trying to pop ", - typeid(*list.back()).name()); + demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ", + demangle(typeid(*list.back()).name()).c_str()); } // Here we're sure that list.back() == this. Whew, pop it. list.pop_back(); @@ -148,7 +148,7 @@ void LLSingletonBase::capture_dependency(EInitState initState) { // 'found' is an iterator; *found is an LLSingletonBase*; **found // is the actual LLSingletonBase instance. - out << typeid(**found).name() << " -> "; + out << demangle(typeid(**found).name()) << " -> "; } // We promise to capture dependencies from both the constructor // and the initSingleton() method, so an LLSingleton's instance @@ -161,7 +161,8 @@ void LLSingletonBase::capture_dependency(EInitState initState) // Decide which log helper to call based on initState. They have // identical signatures. ((initState == CONSTRUCTING)? logerrs : logwarns) - ("LLSingleton circularity: ", out.str().c_str(), typeid(*this).name(), ""); + ("LLSingleton circularity: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); } else { @@ -232,12 +233,12 @@ void LLSingletonBase::cleanupAll() } catch (const std::exception& e) { - logwarns("Exception in ", typeid(*sp).name(), + logwarns("Exception in ", demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton(): ", e.what()); } catch (...) { - logwarns("Unknown exception in ", typeid(*sp).name(), + logwarns("Unknown exception in ", demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()"); } } @@ -252,14 +253,14 @@ void LLSingletonBase::deleteAll() { // Capture the class name first: in case of exception, don't count on // being able to extract it later. - const char* name = typeid(*sp).name(); + const std::string name = demangle(typeid(*sp).name()); try { // Call static method through instance function pointer. if (! sp->mDeleteSingleton) { // This Should Not Happen... but carry on. - logwarns(name, "::mDeleteSingleton not initialized!"); + logwarns(name.c_str(), "::mDeleteSingleton not initialized!"); } else { @@ -270,11 +271,11 @@ void LLSingletonBase::deleteAll() } catch (const std::exception& e) { - logwarns("Exception in ", name, "::deleteSingleton(): ", e.what()); + logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what()); } catch (...) { - logwarns("Unknown exception in ", name, "::deleteSingleton()"); + logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()"); } } } @@ -348,3 +349,8 @@ void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, c std::cerr << p1 << p2 << p3 << p4 << std::endl; } } + +std::string LLSingletonBase::demangle(const char* mangled) +{ + return LLError::Log::demangle(mangled); +} diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index a82101c367..253e0b9a6b 100755 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -104,6 +104,7 @@ protected: // delegate LL_WARNS() logging to llsingleton.cpp static void logwarns(const char* p1, const char* p2="", const char* p3="", const char* p4=""); + static std::string demangle(const char* mangled); // obtain canonical ref_ptr_t static ref_ptr_t get_master_refcount(); @@ -337,11 +338,13 @@ public: { case UNINITIALIZED: // should never be uninitialized at this point - logerrs("Uninitialized singleton ", typeid(DERIVED_TYPE).name()); + logerrs("Uninitialized singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str()); return NULL; case CONSTRUCTING: - logerrs("Tried to access singleton ", typeid(DERIVED_TYPE).name(), + logerrs("Tried to access singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str(), " from singleton constructor!"); return NULL; @@ -361,7 +364,8 @@ public: break; case DELETED: - logwarns("Trying to access deleted singleton ", typeid(DERIVED_TYPE).name(), + logwarns("Trying to access deleted singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str(), " -- creating new instance"); SingletonLifetimeManager::construct(); // same as first time construction -- cgit v1.3 From eddce74206328f213d83c9a76432645a7d3dbc22 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 30 Aug 2016 14:08:32 -0400 Subject: MAINT-5232: Do less work inside typeid() calls. clang gets nervous about expressions that call functions inside typeid(), even though these particular typeid() calls are runtime expressions on runtime values. Extract the offending calls to a previous statement. --- indra/llcommon/llsingleton.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index b78110296f..8c8ded0e51 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -115,9 +115,10 @@ void LLSingletonBase::pop_initializing() } if (list.back() != this) { + LLSingletonBase* back(list.back()); logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ", - demangle(typeid(*list.back()).name()).c_str()); + demangle(typeid(*back).name()).c_str()); } // Here we're sure that list.back() == this. Whew, pop it. list.pop_back(); @@ -148,7 +149,8 @@ void LLSingletonBase::capture_dependency(EInitState initState) { // 'found' is an iterator; *found is an LLSingletonBase*; **found // is the actual LLSingletonBase instance. - out << demangle(typeid(**found).name()) << " -> "; + LLSingletonBase* foundp(*found); + out << demangle(typeid(*foundp).name()) << " -> "; } // We promise to capture dependencies from both the constructor // and the initSingleton() method, so an LLSingleton's instance -- cgit v1.3 From 37d3993a59f01bae55049b08d196733121b54f7f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 30 Aug 2016 16:42:24 -0400 Subject: MAINT-5232: Consolidate special LLSingletonBase logging logic. --- indra/llcommon/llsingleton.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 8c8ded0e51..c3e8f6c7c7 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -316,8 +316,9 @@ void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc) } /*---------------------------- Logging helpers -----------------------------*/ -//static -void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4) +namespace { +void log(LLError::ELevel level, + const char* p1, const char* p2, const char* p3, const char* p4) { // Check LLError::is_available() because some of LLError's infrastructure // is itself an LLSingleton. If that LLSingleton has not yet been @@ -325,31 +326,30 @@ void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, co // around and around we go. if (LLError::is_available()) { - LL_ERRS() << p1 << p2 << p3 << p4 << LL_ENDL; + lllog(level, false) << p1 << p2 << p3 << p4 << LL_ENDL; } else { // Caller may be a test program, or something else whose stderr is // visible to the user. std::cerr << p1 << p2 << p3 << p4 << std::endl; - // The other important side effect of LL_ERRS() is - // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG) - LLError::crashAndLoop(std::string()); } } +} // anonymous namespace //static void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4) { - // See logerrs() remarks about is_available(). - if (LLError::is_available()) - { - LL_WARNS() << p1 << p2 << p3 << p4 << LL_ENDL; - } - else - { - std::cerr << p1 << p2 << p3 << p4 << std::endl; - } + log(LLError::LEVEL_WARN, p1, p2, p3, p4); +} + +//static +void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4) +{ + log(LLError::LEVEL_ERROR, p1, p2, p3, p4); + // The other important side effect of LL_ERRS() is + // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG) + LLError::crashAndLoop(std::string()); } std::string LLSingletonBase::demangle(const char* mangled) -- cgit v1.3 From f5ccfff54299becdbff81661622375d319e5ea7b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 31 Aug 2016 14:25:55 -0400 Subject: MAINT-5232: Add DEBUG logging to LLSingleton operations. Specifically, log as LLSingleton captures inter-Singleton dependencies. Also log cleanupAll() calls to cleanupSingleton() and deleteAll() calls to deleteSingleton(), since they happen in an implicitly-determined order. But do not log anything during the implicit LLSingletonBase::deleteAll() call triggered by the runtime destroying the last LLSingleton's static data. That's too late in the run; even std::cerr might already have been destroyed! --- indra/llcommon/llsingleton.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index c3e8f6c7c7..76789e438e 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -36,6 +36,11 @@ #include #include +namespace { +void log(LLError::ELevel level, + const char* p1="", const char* p2="", const char* p3="", const char* p4=""); +} // anonymous namespace + // Our master list of all LLSingletons is itself an LLSingleton. We used to // store it in a function-local static, but that could get destroyed before // the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to @@ -172,7 +177,13 @@ void LLSingletonBase::capture_dependency(EInitState initState) // Record the dependency. // initializing.back() is the LLSingletonBase* currently being // initialized. Store 'this' in its mDepends set. - initializing.back()->mDepends.insert(this); + LLSingletonBase* current(initializing.back()); + if (current->mDepends.insert(this).second) + { + // only log the FIRST time we hit this dependency! + log(LLError::LEVEL_DEBUG, demangle(typeid(*current).name()).c_str(), + " depends on ", demangle(typeid(*this).name()).c_str()); + } } } } @@ -229,6 +240,8 @@ void LLSingletonBase::cleanupAll() { sp->mCleaned = true; + log(LLError::LEVEL_DEBUG, "calling ", + demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()"); try { sp->cleanupSingleton(); @@ -267,6 +280,7 @@ void LLSingletonBase::deleteAll() else { // properly initialized: call it. + log(LLError::LEVEL_DEBUG, "calling ", name.c_str(), "::deleteSingleton()"); // From this point on, DO NOT DEREFERENCE sp! sp->mDeleteSingleton(); } @@ -320,6 +334,19 @@ namespace { void log(LLError::ELevel level, const char* p1, const char* p2, const char* p3, const char* p4) { + // Check whether we're in the implicit final LLSingletonBase::deleteAll() + // call. We've carefully arranged for deleteAll() to be called when the + // last SingletonLifetimeManager instance is destroyed -- in other words, + // when the last translation unit containing an LLSingleton instance + // cleans up static data. That could happen after std::cerr is destroyed! + // The is_available() test below ensures that we'll stop logging once + // LLError has been cleaned up. If we had a similar portable test for + // std::cerr, this would be a good place to use it. As we do not, just + // don't log anything during implicit final deleteAll(). Detect that by + // the master refcount having gone to zero. + if (sMasterRefcount.refcount == 0) + return; + // Check LLError::is_available() because some of LLError's infrastructure // is itself an LLSingleton. If that LLSingleton has not yet been // initialized, trying to log will engage LLSingleton machinery... and -- cgit v1.3 From 334eb89d8e993c05511f858b6a36732e7dd659df Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 31 Aug 2016 16:17:50 -0400 Subject: MAINT-5232: Add a tag to LLSingleton log messages. --- indra/llcommon/llsingleton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 76789e438e..4212014e1b 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -353,7 +353,7 @@ void log(LLError::ELevel level, // around and around we go. if (LLError::is_available()) { - lllog(level, false) << p1 << p2 << p3 << p4 << LL_ENDL; + lllog(level, false, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL; } else { -- cgit v1.3 From 56a83d2115f3dc55902a3a9aa43afbfeeb4a462a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 1 Sep 2016 19:53:56 -0400 Subject: MAINT-5011: Use LL_VLOGS() rather than raw lllog() macro. Raw lllog() doesn't work for varying log level, which is why LL_VLOGS() exists. --- indra/llcommon/llsingleton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 4212014e1b..cd5c2a7f0e 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -353,7 +353,7 @@ void log(LLError::ELevel level, // around and around we go. if (LLError::is_available()) { - lllog(level, false, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL; + LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL; } else { -- cgit v1.3 From c71e6222295a1fb183436b5d67c21bffddfaefa6 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 3 Sep 2016 11:30:53 -0400 Subject: MAINT-5232: Add DEBUG logging to LLSingleton dependency tracking. Specifically, add DEBUG logging to the code that maintains the stack of LLSingletons currently being initialized. This involves passing LLSingletonBase's constructor the name of LLSingleton's template parameter subclass, since during that constructor typeid(*this).name() will only produce "LLSingletonBase". Also add logdebugs() and oktolog() helper functions. --- indra/llcommon/llsingleton.cpp | 67 ++++++++++++++++++++++++++++++++++-------- indra/llcommon/llsingleton.h | 16 +++++++--- 2 files changed, 66 insertions(+), 17 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index cd5c2a7f0e..479244400d 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -38,7 +38,11 @@ namespace { void log(LLError::ELevel level, - const char* p1="", const char* p2="", const char* p3="", const char* p4=""); + const char* p1, const char* p2, const char* p3, const char* p4); + +void logdebugs(const char* p1="", const char* p2="", const char* p3="", const char* p4=""); + +bool oktolog(); } // anonymous namespace // Our master list of all LLSingletons is itself an LLSingleton. We used to @@ -95,38 +99,64 @@ LLSingletonBase::list_t& LLSingletonBase::get_initializing() return sList; } -LLSingletonBase::LLSingletonBase(): +LLSingletonBase::LLSingletonBase(const char* name): mCleaned(false), mDeleteSingleton(NULL) { // Make this the currently-initializing LLSingleton. - push_initializing(); + push_initializing(name); } LLSingletonBase::~LLSingletonBase() {} -void LLSingletonBase::push_initializing() +void LLSingletonBase::push_initializing(const char* name) { + // log BEFORE pushing so logging singletons don't cry circularity + log_initializing("Pushing", name); get_initializing().push_back(this); } void LLSingletonBase::pop_initializing() { list_t& list(get_initializing()); + if (list.empty()) { logerrs("Underflow in stack of currently-initializing LLSingletons at ", demangle(typeid(*this).name()).c_str(), "::getInstance()"); } - if (list.back() != this) + + // Now we know list.back() exists: capture it + LLSingletonBase* back(list.back()); + // and pop it + list.pop_back(); + + if (back != this) { - LLSingletonBase* back(list.back()); logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ", demangle(typeid(*back).name()).c_str()); } - // Here we're sure that list.back() == this. Whew, pop it. - list.pop_back(); + + // log AFTER popping so logging singletons don't cry circularity + log_initializing("Popping", typeid(*back).name()); +} + +//static +void LLSingletonBase::log_initializing(const char* verb, const char* name) +{ + if (oktolog()) + { + LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';'; + list_t& list(get_initializing()); + for (list_t::const_reverse_iterator ri(list.rbegin()), rend(list.rend()); + ri != rend; ++ri) + { + LLSingletonBase* sb(*ri); + LL_CONT << ' ' << demangle(typeid(*sb).name()); + } + LL_ENDL; + } } void LLSingletonBase::capture_dependency(EInitState initState) @@ -181,8 +211,8 @@ void LLSingletonBase::capture_dependency(EInitState initState) if (current->mDepends.insert(this).second) { // only log the FIRST time we hit this dependency! - log(LLError::LEVEL_DEBUG, demangle(typeid(*current).name()).c_str(), - " depends on ", demangle(typeid(*this).name()).c_str()); + logdebugs(demangle(typeid(*current).name()).c_str(), + " depends on ", demangle(typeid(*this).name()).c_str()); } } } @@ -240,8 +270,8 @@ void LLSingletonBase::cleanupAll() { sp->mCleaned = true; - log(LLError::LEVEL_DEBUG, "calling ", - demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()"); + logdebugs("calling ", + demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()"); try { sp->cleanupSingleton(); @@ -280,7 +310,7 @@ void LLSingletonBase::deleteAll() else { // properly initialized: call it. - log(LLError::LEVEL_DEBUG, "calling ", name.c_str(), "::deleteSingleton()"); + logdebugs("calling ", name.c_str(), "::deleteSingleton()"); // From this point on, DO NOT DEREFERENCE sp! sp->mDeleteSingleton(); } @@ -331,6 +361,12 @@ void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc) /*---------------------------- Logging helpers -----------------------------*/ namespace { +bool oktolog() +{ + // See comments in log() below. + return sMasterRefcount.refcount && LLError::is_available(); +} + void log(LLError::ELevel level, const char* p1, const char* p2, const char* p3, const char* p4) { @@ -362,6 +398,11 @@ void log(LLError::ELevel level, std::cerr << p1 << p2 << p3 << p4 << std::endl; } } + +void logdebugs(const char* p1, const char* p2, const char* p3, const char* p4) +{ + log(LLError::LEVEL_DEBUG, p1, p2, p3, p4); +} } // anonymous namespace //static diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 6a7f27bed4..78092fdc11 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -66,8 +66,10 @@ protected: } EInitState; // Base-class constructor should only be invoked by the DERIVED_TYPE - // constructor. - LLSingletonBase(); + // constructor, which passes the DERIVED_TYPE class name for logging + // purposes. Within LLSingletonBase::LLSingletonBase, of course the + // formula typeid(*this).name() produces "LLSingletonBase". + LLSingletonBase(const char* name); virtual ~LLSingletonBase(); // Every new LLSingleton should be added to/removed from the master list @@ -87,11 +89,15 @@ protected: // single C++ scope, else we'd use RAII to track it. But we do know that // LLSingletonBase's constructor definitely runs just before // LLSingleton's, which runs just before the specific subclass's. - void push_initializing(); + void push_initializing(const char*); // LLSingleton is, and must remain, the only caller to initSingleton(). // That being the case, we control exactly when it happens -- and we can // pop the stack immediately thereafter. void pop_initializing(); +private: + // logging + static void log_initializing(const char* verb, const char* name); +protected: // If a given call to B::getInstance() happens during either A::A() or // A::initSingleton(), record that A directly depends on B. void capture_dependency(EInitState); @@ -281,7 +287,9 @@ private: }; protected: - LLSingleton() + // Use typeid(DERIVED_TYPE) rather than typeid(*this) because, until our + // constructor completes, *this isn't yet a full-fledged DERIVED_TYPE. + LLSingleton(): LLSingletonBase(typeid(DERIVED_TYPE).name()) { // populate base-class function pointer with the static // deleteSingleton() function for this particular specialization -- cgit v1.3 From 90f424980a3aba06ac85cc23373795bc53a3fd87 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 6 Sep 2016 21:07:38 -0400 Subject: MAINT-5232: Make LLSingleton's 'initializing' stack coro-specific. The stack we maintain of which LLSingletons are currently initializing only makes sense when associated with a particular C++ call stack. But each coroutine introduces another C++ call stack! Move the initializing stack from function-static storage to LLSingletonBase::MasterList. Make it a map keyed by llcoro::id. Each coro then has a stack of its own. This introduces more dependencies on the MasterList singleton, requiring additional LLSingleton_manage_master workarounds. --- indra/llcommon/llsingleton.cpp | 54 +++++++++++++++++++++++++++++------------ indra/llcommon/llsingleton.h | 55 +++++++++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 27 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 479244400d..3f65820f2e 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -30,7 +30,9 @@ #include "llerror.h" #include "llerrorcontrol.h" // LLError::is_available() #include "lldependencies.h" +#include "llcoro_get_id.h" #include +#include #include #include // std::cerr in dire emergency #include @@ -61,13 +63,43 @@ private: public: // No need to make this private with accessors; nobody outside this source // file can see it. - LLSingletonBase::list_t mList; + + // This is the master list of all instantiated LLSingletons (save the + // MasterList itself) in arbitrary order. You MUST call dep_sort() before + // traversing this list. + LLSingletonBase::list_t mMaster; + + // We need to maintain a stack of LLSingletons currently being + // initialized, either in the constructor or in initSingleton(). However, + // managing that as a stack depends on having a DISTINCT 'initializing' + // stack for every C++ stack in the process! And we have a distinct C++ + // stack for every running coroutine. It would be interesting and cool to + // implement a generic coroutine-local-storage mechanism and use that + // here. The trouble is that LLCoros is itself an LLSingleton, so + // depending on LLCoros functionality could dig us into infinite + // recursion. (Moreover, when we reimplement LLCoros on top of + // Boost.Fiber, that library already provides fiber_specific_ptr -- so + // it's not worth a great deal of time and energy implementing a generic + // equivalent on top of boost::dcoroutine, which is on its way out.) + // Instead, use a map of llcoro::id to select the appropriate + // coro-specific 'initializing' stack. llcoro::get_id() is carefully + // implemented to avoid requiring LLCoros. + typedef boost::unordered_map InitializingMap; + InitializingMap mInitializing; + + // non-static method, cf. LLSingletonBase::get_initializing() + list_t& get_initializing_() + { + // map::operator[] has find-or-create semantics, exactly what we need + // here. It returns a reference to the selected mapped_type instance. + return mInitializing[llcoro::get_id()]; + } }; //static LLSingletonBase::list_t& LLSingletonBase::get_master() { - return LLSingletonBase::MasterList::instance().mList; + return LLSingletonBase::MasterList::instance().mMaster; } void LLSingletonBase::add_master() @@ -88,23 +120,16 @@ void LLSingletonBase::remove_master() get_master().remove(this); } -// Wrapping our initializing list in a static method ensures that it will be -// constructed on demand. This list doesn't also need to be in an LLSingleton -// because (a) it should be empty by program shutdown and (b) none of our -// destructors reference it. //static LLSingletonBase::list_t& LLSingletonBase::get_initializing() { - static list_t sList; - return sList; + return LLSingletonBase::MasterList::instance().get_initializing_(); } -LLSingletonBase::LLSingletonBase(const char* name): - mCleaned(false), - mDeleteSingleton(NULL) +//static +LLSingletonBase::list_t& LLSingletonBase::get_initializing_from(MasterList* master) { - // Make this the currently-initializing LLSingleton. - push_initializing(name); + return master->get_initializing_();; } LLSingletonBase::~LLSingletonBase() {} @@ -159,13 +184,12 @@ void LLSingletonBase::log_initializing(const char* verb, const char* name) } } -void LLSingletonBase::capture_dependency(EInitState initState) +void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initState) { // Did this getInstance() call come from another LLSingleton, or from // vanilla application code? Note that although this is a nontrivial // method, the vast majority of its calls arrive here with initializing // empty(). - list_t& initializing(get_initializing()); if (! initializing.empty()) { // getInstance() is being called by some other LLSingleton. But -- is diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 78092fdc11..92fba4c1a8 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -46,6 +46,7 @@ private: // This, on the other hand, is a stack whose top indicates the LLSingleton // currently being initialized. static list_t& get_initializing(); + static list_t& get_initializing_from(MasterList*); // Produce a vector of master list, in dependency order. typedef std::vector vec_t; static vec_t dep_sort(); @@ -65,11 +66,19 @@ protected: DELETED } EInitState; + // Define tag to pass to our template constructor. You can't explicitly + // invoke a template constructor with ordinary template syntax: + // http://stackoverflow.com/a/3960925/5533635 + template + struct tag + { + typedef T type; + }; + // Base-class constructor should only be invoked by the DERIVED_TYPE - // constructor, which passes the DERIVED_TYPE class name for logging - // purposes. Within LLSingletonBase::LLSingletonBase, of course the - // formula typeid(*this).name() produces "LLSingletonBase". - LLSingletonBase(const char* name); + // constructor, which passes tag for various purposes. + template + LLSingletonBase(tag); virtual ~LLSingletonBase(); // Every new LLSingleton should be added to/removed from the master list @@ -100,7 +109,7 @@ private: protected: // If a given call to B::getInstance() happens during either A::A() or // A::initSingleton(), record that A directly depends on B. - void capture_dependency(EInitState); + void capture_dependency(list_t& initializing, EInitState); // delegate LL_ERRS() logging to llsingleton.cpp static void logerrs(const char* p1, const char* p2="", @@ -171,12 +180,15 @@ void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount*); void intrusive_ptr_release(LLSingletonBase::MasterRefcount*); // Most of the time, we want LLSingleton_manage_master() to forward its -// methods to LLSingletonBase::add_master() and remove_master(). +// methods to real LLSingletonBase methods. template struct LLSingleton_manage_master { void add(LLSingletonBase* sb) { sb->add_master(); } void remove(LLSingletonBase* sb) { sb->remove_master(); } + void push_initializing(LLSingletonBase* sb) { sb->push_initializing(typeid(T).name()); } + void pop_initializing (LLSingletonBase* sb) { sb->pop_initializing(); } + LLSingletonBase::list_t& get_initializing(T*) { return LLSingletonBase::get_initializing(); } }; // But for the specific case of LLSingletonBase::MasterList, don't. @@ -185,8 +197,24 @@ struct LLSingleton_manage_master { void add(LLSingletonBase*) {} void remove(LLSingletonBase*) {} + void push_initializing(LLSingletonBase*) {} + void pop_initializing (LLSingletonBase*) {} + LLSingletonBase::list_t& get_initializing(LLSingletonBase::MasterList* instance) + { + return LLSingletonBase::get_initializing_from(instance); + } }; +// Now we can implement LLSingletonBase's template constructor. +template +LLSingletonBase::LLSingletonBase(tag): + mCleaned(false), + mDeleteSingleton(NULL) +{ + // Make this the currently-initializing LLSingleton. + LLSingleton_manage_master().push_initializing(this); +} + /** * LLSingleton implements the getInstance() method part of the Singleton * pattern. It can't make the derived class constructors protected, though, so @@ -287,9 +315,10 @@ private: }; protected: - // Use typeid(DERIVED_TYPE) rather than typeid(*this) because, until our - // constructor completes, *this isn't yet a full-fledged DERIVED_TYPE. - LLSingleton(): LLSingletonBase(typeid(DERIVED_TYPE).name()) + // Pass DERIVED_TYPE explicitly to LLSingletonBase's constructor because, + // until our subclass constructor completes, *this isn't yet a + // full-fledged DERIVED_TYPE. + LLSingleton(): LLSingletonBase(LLSingletonBase::tag()) { // populate base-class function pointer with the static // deleteSingleton() function for this particular specialization @@ -363,7 +392,7 @@ public: // breaking cyclic dependencies sData.mInstance->initSingleton(); // pop this off stack of initializing singletons - sData.mInstance->pop_initializing(); + LLSingleton_manage_master().pop_initializing(sData.mInstance); break; case INITIALIZED: @@ -378,7 +407,7 @@ public: sData.mInitState = INITIALIZED; sData.mInstance->initSingleton(); // pop this off stack of initializing singletons - sData.mInstance->pop_initializing(); + LLSingleton_manage_master().pop_initializing(sData.mInstance); break; } @@ -387,7 +416,9 @@ public: // an LLSingleton that directly depends on DERIVED_TYPE. If this call // came from another LLSingleton, rather than from vanilla application // code, record the dependency. - sData.mInstance->capture_dependency(sData.mInitState); + sData.mInstance->capture_dependency( + LLSingleton_manage_master().get_initializing(sData.mInstance), + sData.mInitState); return sData.mInstance; } -- cgit v1.3 From 1cadeb40df15c1eaef3410064f9a2b8e4489082d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 6 Sep 2016 21:25:57 -0400 Subject: MAINT-5232: Prevent runaway LLSingletonBase::MasterList growth. Until we reimplement LLCoros on Boost.Fiber, we must hand-implement coroutine-local data. That presently takes the form of a map keyed on llcoro::id, whose values are the stacks of currently-initializing LLSingleton instances. But since the viewer launches an open-ended number of coroutines, we could end up with an open-ended number of map entries unless we intentionally prune the map. So every time we pop the stack to empty, remove that map entry. This could result in thrashing, a given coroutine's 'initializing' stack being created and deleted for almost every LLSingleton instantiated by that coroutine -- but the number of different LLSingletons is necessarily static, and the lifespan of each is the entire rest of the process. Even a couple dozen LLSingletons won't thrash that badly. --- indra/llcommon/llsingleton.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 3f65820f2e..24ccc8ddb4 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -94,6 +94,15 @@ public: // here. It returns a reference to the selected mapped_type instance. return mInitializing[llcoro::get_id()]; } + + void cleanup_initializing_() + { + InitializingMap::iterator found = mInitializing.find(llcoro::get_id()); + if (found != mInitializing.end()) + { + mInitializing.erase(found); + } + } }; //static @@ -129,7 +138,7 @@ LLSingletonBase::list_t& LLSingletonBase::get_initializing() //static LLSingletonBase::list_t& LLSingletonBase::get_initializing_from(MasterList* master) { - return master->get_initializing_();; + return master->get_initializing_(); } LLSingletonBase::~LLSingletonBase() {} @@ -156,6 +165,17 @@ void LLSingletonBase::pop_initializing() // and pop it list.pop_back(); + // The viewer launches an open-ended number of coroutines. While we don't + // expect most of them to initialize LLSingleton instances, our present + // get_initializing() logic could lead to an open-ended number of map + // entries. So every time we pop the stack back to empty, delete the entry + // entirely. + if (list.empty()) + { + MasterList::instance().cleanup_initializing_(); + } + + // Now validate the newly-popped LLSingleton. if (back != this) { logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", -- cgit v1.3 From d2c3c2f9fe197b1856e9a8ed37aeb56b77e2ff07 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 15 Sep 2016 20:18:12 -0400 Subject: MAINT-5232: Normalize LLSingleton subclasses. A shocking number of LLSingleton subclasses had public constructors -- and in several instances, were being explicitly instantiated independently of the LLSingleton machinery. This breaks the new LLSingleton dependency-tracking machinery. It seems only fair that if you say you want an LLSingleton, there should only be ONE INSTANCE! Introduce LLSINGLETON() and LLSINGLETON_EMPTY_CTOR() macros. These handle the friend class LLSingleton; and explicitly declare a private nullary constructor. To try to enforce the LLSINGLETON() convention, introduce a new pure virtual LLSingleton method you_must_use_LLSINGLETON_macro() which is, as you might suspect, defined by the macro. If you declare an LLSingleton subclass without using LLSINGLETON() or LLSINGLETON_EMPTY_CTOR() in the class body, you can't instantiate the subclass for lack of a you_must_use_LLSINGLETON_macro() implementation -- which will hopefully remind the coder. Trawl through ALL LLSingleton subclass definitions, sprinkling in LLSINGLETON() or LLSINGLETON_EMPTY_CTOR() as appropriate. Remove all explicit constructor declarations, public or private, along with relevant 'friend class LLSingleton' declarations. Where destructors are declared, move them into private section as well. Where the constructor was inline but nontrivial, move out of class body. Fix several LLSingleton abuses revealed by making ctors/dtors private: LLGlobalEconomy was both an LLSingleton and the base class for LLRegionEconomy, a non-LLSingleton. (Therefore every LLRegionEconomy instance contained another instance of the LLGlobalEconomy "singleton.") Extract LLBaseEconomy; LLGlobalEconomy is now a trivial subclass of that. LLRegionEconomy, as you might suspect, now derives from LLBaseEconomy. LLToolGrab, an LLSingleton, was also explicitly instantiated by LLToolCompGun's constructor. Extract LLToolGrabBase, explicitly instantiated, with trivial subclass LLToolGrab, the LLSingleton instance. (WARNING: LLToolGrabBase methods have an unnerving tendency to go after LLToolGrab::getInstance(). I DO NOT KNOW what should be the relationship between the instance in LLToolCompGun and the LLToolGrab singleton instance.) LLGridManager declared a variant constructor accepting (const std::string&), with the comment: // initialize with an explicity grid file for testing. As there is no evidence of this being called from anywhere, delete it. LLChicletBar's constructor accepted an optional (const LLSD&). As the LLSD parameter wasn't used, and as there is no evidence of it being passed from anywhere, delete the parameter. LLViewerWindow::shutdownViews() was checking LLNavigationBar:: instanceExists(), then deleting its getInstance() pointer -- leaving a dangling LLSingleton instance pointer, a land mine if any subsequent code should attempt to reference it. Use deleteSingleton() instead. ~LLAppViewer() was calling LLViewerEventRecorder::instance() and then explicitly calling ~LLViewerEventRecorder() on that instance -- leaving the LLSingleton instance pointer pointing to an allocated-but-destroyed instance. Use deleteSingleton() instead. --- indra/llappearance/llavatarappearancedefines.h | 3 +- indra/llappearance/lltexlayer.h | 4 +- indra/llappearance/llwearabletype.cpp | 3 +- indra/llcommon/llassettype.cpp | 3 +- indra/llcommon/llcoros.h | 3 +- indra/llcommon/llerror.cpp | 9 +- indra/llcommon/llevents.h | 3 +- indra/llcommon/llinitdestroyclass.h | 8 +- indra/llcommon/llpounceable.h | 3 +- indra/llcommon/llregistry.h | 5 +- indra/llcommon/llsingleton.cpp | 3 +- indra/llcommon/llsingleton.h | 68 ++++++- indra/llcommon/tests/llsingleton_test.cpp | 31 ++-- indra/llinventory/lleconomy.cpp | 25 ++- indra/llinventory/lleconomy.h | 14 +- indra/llinventory/llfoldertype.cpp | 3 +- indra/llinventory/llinventorytype.cpp | 3 +- indra/llmessage/llcoproceduremanager.h | 6 +- indra/llmessage/llexperiencecache.h | 3 +- indra/llmessage/llproxy.h | 8 +- indra/llmessage/message.h | 4 +- indra/llmessage/tests/networkio.h | 3 +- indra/llui/llclipboard.h | 4 +- indra/llui/llcommandmanager.h | 6 +- indra/llui/llcontainerview.h | 4 +- indra/llui/llfunctorregistry.h | 16 +- indra/llui/lllayoutstack.h | 4 +- indra/llui/llmenugl.h | 4 +- indra/llui/llnotifications.h | 4 +- indra/llui/llpanel.h | 3 +- indra/llui/llresmgr.h | 4 +- indra/llui/llscrollcontainer.h | 4 +- indra/llui/llspellcheck.h | 4 +- indra/llui/llstatview.h | 4 +- indra/llui/lltextparser.h | 4 +- indra/llui/lltooltip.h | 3 +- indra/llui/lluicolortable.h | 3 +- indra/llui/lluictrl.h | 13 +- indra/llui/lluictrlfactory.h | 52 +++--- indra/llui/llurlregistry.h | 7 +- indra/llui/llview.cpp | 2 + indra/llui/llviewereventrecorder.h | 7 +- indra/llui/llviewquery.h | 6 + indra/llui/llxuiparser.h | 8 +- indra/media_plugins/cef/windows_volume_catcher.cpp | 9 +- indra/newview/llaccountingcostmanager.h | 4 +- indra/newview/llagentpicksinfo.h | 8 +- indra/newview/llappearancemgr.h | 7 +- indra/newview/llappviewer.cpp | 3 +- indra/newview/llattachmentsmgr.h | 6 +- indra/newview/llautoreplace.h | 3 +- indra/newview/llavataractions.cpp | 2 + indra/newview/llavatariconctrl.h | 11 +- indra/newview/llavatarpropertiesprocessor.h | 7 +- indra/newview/llavatarrenderinfoaccountant.h | 6 +- indra/newview/llavatarrendernotifier.h | 4 +- indra/newview/llchannelmanager.h | 6 +- indra/newview/llchicletbar.cpp | 2 +- indra/newview/llchicletbar.h | 5 +- indra/newview/llconversationlog.h | 3 +- indra/newview/lldaycyclemanager.h | 2 +- indra/newview/lldeferredsounds.h | 2 +- .../newview/lldonotdisturbnotificationstorage.cpp | 3 +- indra/newview/lldonotdisturbnotificationstorage.h | 6 +- indra/newview/llenvmanager.h | 4 +- indra/newview/llestateinfomodel.h | 4 +- indra/newview/llexperiencelog.h | 3 +- indra/newview/llfacebookconnect.h | 5 +- indra/newview/llfavoritesbar.h | 11 +- indra/newview/llfeaturemanager.h | 26 +-- indra/newview/llflickrconnect.h | 5 +- indra/newview/llfriendcard.h | 5 +- indra/newview/llgesturemgr.h | 4 +- indra/newview/llgroupmgr.h | 4 +- indra/newview/llhudmanager.h | 4 +- indra/newview/llimagefiltersmanager.h | 5 +- indra/newview/llimview.h | 5 +- indra/newview/llinventoryicon.cpp | 3 +- indra/newview/llinventorymodelbackgroundfetch.h | 4 +- indra/newview/lllocationhistory.h | 2 +- indra/newview/lllogchat.cpp | 19 +- indra/newview/lllogininstance.h | 6 +- indra/newview/llmainlooprepeater.h | 3 +- indra/newview/llmarketplacefunctions.h | 13 +- indra/newview/llmaterialmgr.h | 4 +- .../llmenuoptionpathfindingrebakenavmesh.cpp | 3 +- .../newview/llmenuoptionpathfindingrebakenavmesh.h | 4 +- indra/newview/llmutelist.h | 4 +- indra/newview/llnavigationbar.h | 6 +- indra/newview/llnotificationmanager.h | 6 +- indra/newview/llnotificationstorage.cpp | 7 +- indra/newview/lloutfitobserver.h | 5 +- indra/newview/llpaneleditwearable.cpp | 3 +- indra/newview/llpanelteleporthistory.cpp | 4 +- indra/newview/llpaneltopinfobar.h | 5 +- indra/newview/llpathfindingmanager.cpp | 3 +- indra/newview/llpathfindingmanager.h | 6 +- indra/newview/llpathfindingpathtool.cpp | 1 - indra/newview/llpathfindingpathtool.h | 6 +- indra/newview/llpersistentnotificationstorage.cpp | 5 +- indra/newview/llpersistentnotificationstorage.h | 4 +- indra/newview/llpresetsmanager.h | 6 +- indra/newview/llproductinforequest.h | 3 +- indra/newview/llrecentpeople.h | 1 + indra/newview/llregioninfomodel.h | 3 +- indra/newview/llremoteparcelrequest.h | 3 +- indra/newview/llrootview.h | 4 +- indra/newview/llscenemonitor.h | 4 +- indra/newview/llscriptfloater.h | 1 + indra/newview/llsearchhistory.h | 2 +- indra/newview/llselectmgr.h | 6 +- indra/newview/llspeakers.h | 8 +- indra/newview/llspeakingindicatormanager.cpp | 6 +- indra/newview/llstylemap.h | 1 + indra/newview/llsyntaxid.h | 5 +- indra/newview/llteleporthistory.h | 5 +- indra/newview/llteleporthistorystorage.h | 5 +- indra/newview/lltextureatlasmanager.h | 5 +- indra/newview/lltoolbrush.h | 2 +- indra/newview/lltoolcomp.cpp | 2 +- indra/newview/lltoolcomp.h | 28 +-- indra/newview/lltooldraganddrop.h | 5 +- indra/newview/lltoolface.h | 4 +- indra/newview/lltoolfocus.h | 4 +- indra/newview/lltoolgrab.cpp | 52 +++--- indra/newview/lltoolgrab.h | 21 ++- indra/newview/lltoolindividual.h | 4 +- indra/newview/lltoolmgr.h | 4 +- indra/newview/lltoolobjpicker.h | 2 +- indra/newview/lltoolpie.h | 2 +- indra/newview/lltoolpipette.h | 4 +- indra/newview/lltoolselectland.h | 4 +- indra/newview/lltransientfloatermgr.h | 4 +- indra/newview/lltwitterconnect.h | 4 +- indra/newview/llviewerassettype.cpp | 3 +- indra/newview/llvieweraudio.h | 6 +- indra/newview/llviewercamera.h | 3 +- indra/newview/llviewerfoldertype.cpp | 3 +- indra/newview/llviewerhelp.h | 2 +- indra/newview/llviewerinventory.cpp | 196 ++++++++++----------- indra/newview/llviewerjoystick.h | 6 +- indra/newview/llviewerkeyboard.cpp | 1 + indra/newview/llviewermediafocus.h | 6 +- indra/newview/llviewermessage.h | 1 + indra/newview/llviewernetwork.cpp | 7 - indra/newview/llviewernetwork.h | 9 +- indra/newview/llviewerparcelmgr.h | 5 +- indra/newview/llviewerpartsim.h | 3 +- indra/newview/llviewerstats.h | 8 +- indra/newview/llviewerstatsrecorder.h | 6 +- indra/newview/llviewertexturelist.h | 1 + indra/newview/llviewerwindow.cpp | 17 +- indra/newview/llvocache.h | 8 +- indra/newview/llvoicechannel.h | 2 +- indra/newview/llvoiceclient.h | 10 +- indra/newview/llvoicevivox.h | 13 +- indra/newview/llwatchdog.h | 4 +- indra/newview/llwaterparammanager.h | 6 +- indra/newview/llwearableitemslist.h | 2 +- indra/newview/llwearablelist.h | 4 +- indra/newview/llwindebug.h | 1 + indra/newview/llwlparammanager.h | 6 +- indra/newview/llworld.h | 2 +- indra/newview/llworldmap.h | 4 +- indra/newview/llworldmapmessage.h | 6 +- 165 files changed, 652 insertions(+), 604 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h index 8a1d2c4707..d6223bb4d2 100644 --- a/indra/llappearance/llavatarappearancedefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -127,8 +127,7 @@ class LLAvatarAppearanceDictionary : public LLSingleton { -public: - LLTexLayerStaticImageList(); + LLSINGLETON(LLTexLayerStaticImageList); ~LLTexLayerStaticImageList(); +public: LLGLTexture* getTexture(const std::string& file_name, BOOL is_mask); LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index 87109a5906..207e0c4011 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -71,8 +71,7 @@ struct WearableEntry : public LLDictionaryEntry class LLWearableDictionary : public LLSingleton, public LLDictionary { -public: - LLWearableDictionary(); + LLSINGLETON(LLWearableDictionary); }; LLWearableDictionary::LLWearableDictionary() diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 5ae2df3994..4304db36be 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -63,8 +63,7 @@ struct AssetEntry : public LLDictionaryEntry class LLAssetDictionary : public LLSingleton, public LLDictionary { -public: - LLAssetDictionary(); + LLSINGLETON(LLAssetDictionary); }; LLAssetDictionary::LLAssetDictionary() diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 0da7a3a6e4..bbe2d22af4 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -85,6 +85,7 @@ class Suspending; */ class LL_COMMON_API LLCoros: public LLSingleton { + LLSINGLETON(LLCoros); public: /// Canonical boost::dcoroutines::coroutine signature we use typedef boost::dcoroutines::coroutine coro; @@ -175,8 +176,6 @@ public: class Future; private: - LLCoros(); - friend class LLSingleton; friend class llcoro::Suspending; friend llcoro::id llcoro::get_id(); std::string generateDistinctName(const std::string& prefix) const; diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index a34b50f816..2ef748e3e4 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -374,9 +374,8 @@ namespace class Globals : public LLSingleton { + LLSINGLETON(Globals); public: - Globals(); - std::ostringstream messageStream; bool messageStreamInUse; @@ -449,9 +448,8 @@ namespace LLError class Settings : public LLSingleton { + LLSINGLETON(Settings); public: - Settings(); - SettingsConfigPtr getSettingsConfig(); void reset(); @@ -486,8 +484,7 @@ namespace LLError mRecorders.clear(); } - Settings::Settings() - : LLSingleton(), + Settings::Settings(): mSettingsConfig(new SettingsConfig()) { } diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index ba4fcd766e..6c8b66f596 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -209,7 +209,7 @@ class LLEventPump; */ class LL_COMMON_API LLEventPumps: public LLSingleton { - friend class LLSingleton; + LLSINGLETON(LLEventPumps); public: /** * Find or create an LLEventPump instance with a specific name. We return @@ -252,7 +252,6 @@ private: void unregister(const LLEventPump&); private: - LLEventPumps(); ~LLEventPumps(); testable: diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h index 9c66211475..5f979614fe 100644 --- a/indra/llcommon/llinitdestroyclass.h +++ b/indra/llcommon/llinitdestroyclass.h @@ -78,9 +78,7 @@ class LLInitClassList : public LLCallbackRegistry, public LLSingleton { - friend class LLSingleton; -private: - LLInitClassList() {} + LLSINGLETON_EMPTY_CTOR(LLInitClassList); }; /** @@ -94,9 +92,7 @@ class LLDestroyClassList : public LLCallbackRegistry, public LLSingleton { - friend class LLSingleton; -private: - LLDestroyClassList() {} + LLSINGLETON_EMPTY_CTOR(LLDestroyClassList); }; /** diff --git a/indra/llcommon/llpounceable.h b/indra/llcommon/llpounceable.h index 77b711bdc6..0421ce966a 100644 --- a/indra/llcommon/llpounceable.h +++ b/indra/llcommon/llpounceable.h @@ -76,7 +76,8 @@ template class LLPounceableQueueSingleton: public LLSingleton > { -private: + LLSINGLETON_EMPTY_CTOR(LLPounceableQueueSingleton); + typedef LLPounceableTraits traits; typedef typename traits::owner_ptr owner_ptr; typedef typename traits::signal_t signal_t; diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index fde729f8f9..750fe9fdc8 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -247,7 +247,10 @@ class LLRegistrySingleton : public LLRegistry, public LLSingleton { - friend class LLSingleton; + // This LLRegistrySingleton doesn't use LLSINGLETON(LLRegistrySingleton) + // because the concrete class is actually DERIVED_TYPE, not + // LLRegistrySingleton. So each concrete subclass needs + // LLSINGLETON(whatever) -- not this intermediate base class. public: typedef LLRegistry registry_t; typedef const KEY& ref_const_key_t; diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 24ccc8ddb4..9025e53bb2 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -57,8 +57,7 @@ bool oktolog(); class LLSingletonBase::MasterList: public LLSingleton { -private: - friend class LLSingleton; + LLSINGLETON_EMPTY_CTOR(MasterList); public: // No need to make this private with accessors; nobody outside this source diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 92fba4c1a8..1b915dfd6e 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -223,7 +223,13 @@ LLSingletonBase::LLSingletonBase(tag): * Derive your class from LLSingleton, passing your subclass name as * LLSingleton's template parameter, like so: * - * class Foo: public LLSingleton{}; + * class Foo: public LLSingleton + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON(Foo); + * public: + * // ... + * }; * * Foo& instance = Foo::instance(); * @@ -279,6 +285,16 @@ private: return new DERIVED_TYPE(); } + // We know of no way to instruct the compiler that every subclass + // constructor MUST be private. However, we can make the LLSINGLETON() + // macro both declare a private constructor and provide the required + // friend declaration. How can we ensure that every subclass uses + // LLSINGLETON()? By making that macro provide a definition for this pure + // virtual method. If you get "can't instantiate class due to missing pure + // virtual method" for this method, then add LLSINGLETON(yourclass) in the + // subclass body. + virtual void you_must_use_LLSINGLETON_macro() = 0; + // stores pointer to singleton instance struct SingletonLifetimeManager { @@ -450,4 +466,54 @@ private: template typename LLSingleton::SingletonData LLSingleton::sData; +/** + * Use LLSINGLETON(Foo); at the start of an LLSingleton subclass body + * when you want to declare an out-of-line constructor: + * + * @code + * class Foo: public LLSingleton + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON(Foo); + * public: + * // ... + * }; + * // ... + * [inline] + * Foo::Foo() { ... } + * @endcode + * + * Unfortunately, this mechanism does not permit you to define even a simple + * (but nontrivial) constructor within the class body. If it's literally + * trivial, use LLSINGLETON_EMPTY_CTOR(); if not, use LLSINGLETON() and define + * the constructor outside the class body. If you must define it in a header + * file, use 'inline' (unless it's a template class) to avoid duplicate-symbol + * errors at link time. + */ +#define LLSINGLETON(DERIVED_CLASS) \ +private: \ + /* implement LLSingleton pure virtual method whose sole purpose */ \ + /* is to remind people to use this macro */ \ + virtual void you_must_use_LLSINGLETON_macro() {} \ + friend class LLSingleton; \ + DERIVED_CLASS() + +/** + * Use LLSINGLETON_EMPTY_CTOR(Foo); at the start of an LLSingleton + * subclass body when the constructor is trivial: + * + * @code + * class Foo: public LLSingleton + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON_EMPTY_CTOR(Foo); + * public: + * // ... + * }; + * @endcode + */ +#define LLSINGLETON_EMPTY_CTOR(DERIVED_CLASS) \ + /* LLSINGLETON() is carefully implemented to permit exactly this */ \ + LLSINGLETON(DERIVED_CLASS) {} + #endif diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp index a05f650f25..56886bc73f 100644 --- a/indra/llcommon/tests/llsingleton_test.cpp +++ b/indra/llcommon/tests/llsingleton_test.cpp @@ -34,21 +34,22 @@ // Capture execution sequence by appending to log string. std::string sLog; -#define DECLARE_CLASS(CLS) \ -struct CLS: public LLSingleton \ -{ \ - static enum dep_flag { \ - DEP_NONE, /* no dependency */ \ - DEP_CTOR, /* dependency in ctor */ \ +#define DECLARE_CLASS(CLS) \ +struct CLS: public LLSingleton \ +{ \ + LLSINGLETON(CLS); \ + ~CLS(); \ +public: \ + static enum dep_flag { \ + DEP_NONE, /* no dependency */ \ + DEP_CTOR, /* dependency in ctor */ \ DEP_INIT /* dependency in initSingleton */ \ - } sDepFlag; \ - \ - CLS(); \ - void initSingleton(); \ - void cleanupSingleton(); \ - ~CLS(); \ -}; \ - \ + } sDepFlag; \ + \ + void initSingleton(); \ + void cleanupSingleton(); \ +}; \ + \ CLS::dep_flag CLS::sDepFlag = DEP_NONE DECLARE_CLASS(A); @@ -93,7 +94,7 @@ namespace tut // We need a class created with the LLSingleton template to test with. class LLSingletonTest: public LLSingleton { - + LLSINGLETON_EMPTY_CTOR(LLSingletonTest); }; }; diff --git a/indra/llinventory/lleconomy.cpp b/indra/llinventory/lleconomy.cpp index e10402196f..2a023d8c24 100644 --- a/indra/llinventory/lleconomy.cpp +++ b/indra/llinventory/lleconomy.cpp @@ -31,7 +31,7 @@ #include "v3math.h" -LLGlobalEconomy::LLGlobalEconomy() +LLBaseEconomy::LLBaseEconomy() : mObjectCount( -1 ), mObjectCapacity( -1 ), mPriceObjectClaim( -1 ), @@ -45,15 +45,15 @@ LLGlobalEconomy::LLGlobalEconomy() mPriceGroupCreate( -1 ) { } -LLGlobalEconomy::~LLGlobalEconomy() +LLBaseEconomy::~LLBaseEconomy() { } -void LLGlobalEconomy::addObserver(LLEconomyObserver* observer) +void LLBaseEconomy::addObserver(LLEconomyObserver* observer) { mObservers.push_back(observer); } -void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer) +void LLBaseEconomy::removeObserver(LLEconomyObserver* observer) { std::list::iterator it = std::find(mObservers.begin(), mObservers.end(), observer); @@ -63,7 +63,7 @@ void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer) } } -void LLGlobalEconomy::notifyObservers() +void LLBaseEconomy::notifyObservers() { for (std::list::iterator it = mObservers.begin(); it != mObservers.end(); @@ -74,7 +74,7 @@ void LLGlobalEconomy::notifyObservers() } // static -void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data) +void LLBaseEconomy::processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data) { S32 i; F32 f; @@ -117,7 +117,7 @@ void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data->notifyObservers(); } -S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const +S32 LLBaseEconomy::calculateTeleportCost(F32 distance) const { S32 min_cost = getTeleportMinPrice(); F32 exponent = getTeleportPriceExponent(); @@ -135,13 +135,13 @@ S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const return cost; } -S32 LLGlobalEconomy::calculateLightRent(const LLVector3& object_size) const +S32 LLBaseEconomy::calculateLightRent(const LLVector3& object_size) const { F32 intensity_mod = llmax(object_size.magVec(), 1.f); return (S32)(intensity_mod * getPriceRentLight()); } -void LLGlobalEconomy::print() +void LLBaseEconomy::print() { LL_INFOS() << "Global Economy Settings: " << LL_ENDL; LL_INFOS() << "Object Capacity: " << mObjectCapacity << LL_ENDL; @@ -159,8 +159,7 @@ void LLGlobalEconomy::print() } LLRegionEconomy::LLRegionEconomy() -: LLGlobalEconomy(), - mPriceObjectRent( -1.f ), +: mPriceObjectRent( -1.f ), mPriceObjectScaleFactor( -1.f ), mEnergyEfficiency( -1.f ), mBasePriceParcelClaimDefault(-1), @@ -187,7 +186,7 @@ void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data) LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data; - LLGlobalEconomy::processEconomyData(msg, this_ptr); + LLBaseEconomy::processEconomyData(msg, this_ptr); msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelClaim, i); this_ptr->setBasePriceParcelClaimDefault(i); @@ -252,7 +251,7 @@ S32 LLRegionEconomy::getPriceParcelRent() const void LLRegionEconomy::print() { - this->LLGlobalEconomy::print(); + this->LLBaseEconomy::print(); LL_INFOS() << "Region Economy Settings: " << LL_ENDL; LL_INFOS() << "Land (square meters): " << mAreaTotal << LL_ENDL; diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h index 83836b7ce1..cdfde171c1 100644 --- a/indra/llinventory/lleconomy.h +++ b/indra/llinventory/lleconomy.h @@ -42,11 +42,11 @@ public: virtual void onEconomyDataChange() = 0; }; -class LLGlobalEconomy: public LLSingleton +class LLBaseEconomy { public: - LLGlobalEconomy(); - virtual ~LLGlobalEconomy(); + LLBaseEconomy(); + virtual ~LLBaseEconomy(); virtual void print(); @@ -54,7 +54,7 @@ public: void removeObserver(LLEconomyObserver* observer); void notifyObservers(); - static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data); + static void processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data); S32 calculateTeleportCost(F32 distance) const; S32 calculateLightRent(const LLVector3& object_size) const; @@ -101,8 +101,12 @@ private: std::list mObservers; }; +class LLGlobalEconomy: public LLSingleton, public LLBaseEconomy +{ + LLSINGLETON_EMPTY_CTOR(LLGlobalEconomy); +}; -class LLRegionEconomy : public LLGlobalEconomy +class LLRegionEconomy : public LLBaseEconomy { public: LLRegionEconomy(); diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 86aca77de8..b0daf639fa 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -51,8 +51,7 @@ struct FolderEntry : public LLDictionaryEntry class LLFolderDictionary : public LLSingleton, public LLDictionary { -public: - LLFolderDictionary(); + LLSINGLETON(LLFolderDictionary); protected: virtual LLFolderType::EType notFound() const { diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 8807b36117..d1e6807f52 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -63,8 +63,7 @@ struct InventoryEntry : public LLDictionaryEntry class LLInventoryDictionary : public LLSingleton, public LLDictionary { -public: - LLInventoryDictionary(); + LLSINGLETON(LLInventoryDictionary); }; LLInventoryDictionary::LLInventoryDictionary() diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 497367b80c..7d0e83180c 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -37,7 +37,8 @@ class LLCoprocedurePool; class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager > { - friend class LLSingleton < LLCoprocedureManager > ; + LLSINGLETON(LLCoprocedureManager); + virtual ~LLCoprocedureManager(); public: typedef boost::function SettingQuery_t; @@ -45,9 +46,6 @@ public: typedef boost::function CoProcedure_t; - LLCoprocedureManager(); - virtual ~LLCoprocedureManager(); - /// Places the coprocedure on the queue for processing. /// /// @param name Is used for debugging and should identify this coroutine. diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h index 1002b33f80..8ee7080d38 100644 --- a/indra/llmessage/llexperiencecache.h +++ b/indra/llmessage/llexperiencecache.h @@ -43,7 +43,7 @@ class LLUUID; class LLExperienceCache: public LLSingleton < LLExperienceCache > { - friend class LLSingleton < LLExperienceCache > ; + LLSINGLETON(LLExperienceCache); public: typedef boost::function CapabilityQuery_t; @@ -103,7 +103,6 @@ public: static const int PROPERTY_SUSPENDED; // 1 << 7 private: - LLExperienceCache(); virtual ~LLExperienceCache(); virtual void initSingleton(); diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index bd23dd39de..688dff7c83 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -218,14 +218,14 @@ enum LLSocks5AuthType */ class LLProxy: public LLSingleton { - LOG_CLASS(LLProxy); -public: /*########################################################################################### METHODS THAT DO NOT LOCK mProxyMutex! ###########################################################################################*/ // Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only. - LLProxy(); + LLSINGLETON(LLProxy); + LOG_CLASS(LLProxy); +public: // Static check for enabled status for UDP packets. Call from main thread only. static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } @@ -239,9 +239,11 @@ public: /*########################################################################################### METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! ###########################################################################################*/ +private: // Destructor, closes open connections. Do not call directly, use cleanupClass(). ~LLProxy(); +public: // Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be // destroyed before the call to apr_terminate. Call from main thread only. static void cleanupClass(); diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 681de441ce..f6c5d9e228 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -69,10 +69,10 @@ const S32 MESSAGE_MAX_PER_FRAME = 400; class LLMessageStringTable : public LLSingleton { -public: - LLMessageStringTable(); + LLSINGLETON(LLMessageStringTable); ~LLMessageStringTable(); +public: char *getString(const char *str); U32 mUsed; diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h index 2aff90ca1e..e579b2fb89 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -43,7 +43,7 @@ // init time. Use the lazy, on-demand initialization we get from LLSingleton. class NetworkIO: public LLSingleton { -public: + LLSINGLETON(NetworkIO); NetworkIO(): mServicePump(NULL), mDone(false) @@ -68,6 +68,7 @@ public: boost::bind(&NetworkIO::done, this, _1)); } +public: bool pump(F32 timeout=10) { // Reset the done flag so we don't pop out prematurely diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h index 58d80e2687..a668ac1ac6 100644 --- a/indra/llui/llclipboard.h +++ b/indra/llui/llclipboard.h @@ -48,10 +48,10 @@ class LLClipboard : public LLSingleton { -public: - LLClipboard(); + LLSINGLETON(LLClipboard); ~LLClipboard(); +public: // Clears the clipboard void reset(); // Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state) diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index f2f2145953..8cec5e2b24 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -173,6 +173,9 @@ private: class LLCommandManager : public LLSingleton { + LLSINGLETON(LLCommandManager); + ~LLCommandManager(); + public: struct Params : public LLInitParam::Block { @@ -184,9 +187,6 @@ public: } }; - LLCommandManager(); - ~LLCommandManager(); - U32 commandCount() const; LLCommand * getCommand(U32 commandIndex); LLCommand * getCommand(const LLCommandId& commandId); diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h index ac92b19977..99267d978a 100644 --- a/indra/llui/llcontainerview.h +++ b/indra/llui/llcontainerview.h @@ -35,7 +35,9 @@ class LLScrollContainer; struct ContainerViewRegistry : public LLChildRegistry -{}; +{ + LLSINGLETON_EMPTY_CTOR(ContainerViewRegistry); +}; class LLContainerView : public LLView { diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index f5364f4863..e43974bc52 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -53,14 +53,8 @@ template class LLFunctorRegistry : public LLSingleton > { - friend class LLSingleton; + LLSINGLETON(LLFunctorRegistry); LOG_CLASS(LLFunctorRegistry); -private: - LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") - { - mMap[LOGFUNCTOR] = log_functor; - mMap[DONOTHING] = do_nothing; - } public: typedef FUNCTOR_TYPE ResponseFunctor; @@ -124,6 +118,14 @@ private: FunctorMap mMap; }; +template +LLFunctorRegistry::LLFunctorRegistry() : + LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") +{ + mMap[LOGFUNCTOR] = log_functor; + mMap[DONOTHING] = do_nothing; +} + template class LLFunctorRegistration { diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index a245ebe1b9..f772dbc6b4 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -40,7 +40,9 @@ class LLLayoutStack : public LLView, public LLInstanceTracker public: struct LayoutStackRegistry : public LLChildRegistry - {}; + { + LLSINGLETON_EMPTY_CTOR(LayoutStackRegistry); + }; struct Params : public LLInitParam::Block { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 628dedb906..c7f7f6848c 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -347,7 +347,9 @@ private: // child widget registry struct MenuRegistry : public LLChildRegistry -{}; +{ + LLSINGLETON_EMPTY_CTOR(MenuRegistry); +}; class LLMenuGL diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 354add0b82..024332ee65 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -884,9 +884,9 @@ class LLNotifications : public LLSingleton, public LLNotificationChannelBase { + LLSINGLETON(LLNotifications); LOG_CLASS(LLNotifications); - friend class LLSingleton; public: // Needed to clear up RefCounted things prior to actual destruction @@ -966,8 +966,6 @@ public: bool isVisibleByRules(LLNotificationPtr pNotification); private: - // we're a singleton, so we don't have a public constructor - LLNotifications(); /*virtual*/ void initSingleton(); void loadPersistentNotifications(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index c2185f24de..b8f47ef6ba 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -268,8 +268,9 @@ typedef boost::function LLPanelClassCreatorFunc; class LLRegisterPanelClass : public LLSingleton< LLRegisterPanelClass > { + LLSINGLETON_EMPTY_CTOR(LLRegisterPanelClass); public: - // reigister with either the provided builder, or the generic templated builder + // register with either the provided builder, or the generic templated builder void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) { mPanelClassesNames[tag] = func; diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h index a652dcd2c0..b19d8d40b8 100644 --- a/indra/llui/llresmgr.h +++ b/indra/llui/llresmgr.h @@ -42,9 +42,9 @@ enum LLLOCALE_ID class LLResMgr : public LLSingleton { -public: - LLResMgr(); + LLSINGLETON(LLResMgr); +public: void setLocale( LLLOCALE_ID locale_id ); LLLOCALE_ID getLocale() const { return mLocale; } diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index f64cf43a8e..c4c4d0a136 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -48,7 +48,9 @@ class LLUICtrlFactory; *****************************************************************************/ struct ScrollContainerRegistry : public LLChildRegistry -{}; +{ + LLSINGLETON_EMPTY_CTOR(ScrollContainerRegistry); +}; class LLScrollContainer : public LLUICtrl { diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h index 5ecc9aa110..acac589e43 100644 --- a/indra/llui/llspellcheck.h +++ b/indra/llui/llspellcheck.h @@ -36,10 +36,8 @@ class Hunspell; class LLSpellChecker : public LLSingleton, public LLInitClass { - friend class LLSingleton; + LLSINGLETON(LLSpellChecker); friend class LLInitClass; -protected: - LLSpellChecker(); ~LLSpellChecker(); public: diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index bc78d3b5fd..af4db7d7ea 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -35,7 +35,9 @@ class LLStatBar; // widget registrars struct StatViewRegistry : public LLChildRegistry -{}; +{ + LLSINGLETON_EMPTY_CTOR(StatViewRegistry); +}; class LLStatView : public LLContainerView { diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h index 400aeeb8be..3d71e40452 100644 --- a/indra/llui/lltextparser.h +++ b/indra/llui/lltextparser.h @@ -37,14 +37,14 @@ class LLColor4; class LLTextParser : public LLSingleton { + LLSINGLETON(LLTextParser); + public: typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType; typedef enum e_highlight_type { PART, ALL } EHighlightType; typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition; typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction; - LLTextParser(); - LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0); bool parseFullLineHighlights(const std::string &text, LLColor4 *color); diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index fad127fc4c..0b1fbe5367 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -129,9 +129,10 @@ public: class LLToolTipMgr : public LLSingleton { + LLSINGLETON(LLToolTipMgr); LOG_CLASS(LLToolTipMgr); + public: - LLToolTipMgr(); void show(const LLToolTip::Params& params); void show(const std::string& message); diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 6a7a681d57..44472070cc 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -38,7 +38,8 @@ class LLUIColor; class LLUIColorTable : public LLSingleton { -LOG_CLASS(LLUIColorTable); + LLSINGLETON_EMPTY_CTOR(LLUIColorTable); + LOG_CLASS(LLUIColorTable); // consider using sorted vector, can be much faster typedef std::map string_color_map_t; diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 99553ee0d2..550bee5c70 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -258,18 +258,25 @@ public: class LLTextInputFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && static_cast(view)->acceptsTextInput(), TRUE); } }; - + template class CallbackRegistry : public LLRegistrySingleton {}; - class CommitCallbackRegistry : public CallbackRegistry{}; + class CommitCallbackRegistry : public CallbackRegistry + { + LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); + }; // the enable callback registry is also used for visiblity callbacks - class EnableCallbackRegistry : public CallbackRegistry{}; + class EnableCallbackRegistry : public CallbackRegistry + { + LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); + }; protected: diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3ce39c947f..0151c896a7 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -57,22 +57,24 @@ protected: class LLDefaultChildRegistry : public LLChildRegistry { -protected: - LLDefaultChildRegistry(){} - friend class LLSingleton; + LLSINGLETON_EMPTY_CTOR(LLDefaultChildRegistry); }; // lookup widget name by type class LLWidgetNameRegistry : public LLRegistrySingleton -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry); +}; // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry //: public LLRegistrySingleton -//{}; +//{ +// LLSINGLETON(LLDefaultParamBlockRegistry); +//}; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION; @@ -85,31 +87,15 @@ extern template class LLUICtrlFactory* LLSingleton::getIn class LLUICtrlFactory : public LLSingleton { -private: - friend class LLSingleton; - LLUICtrlFactory(); + LLSINGLETON(LLUICtrlFactory); ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter template class ParamDefaults : public LLSingleton > { + LLSINGLETON(ParamDefaults); public: - ParamDefaults() - { - // look up template file for this param block... - const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); - if (param_block_tag) - { // ...and if it exists, back fill values using the most specific template first - PARAM_BLOCK params; - LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); - mPrototype.fillFrom(params); - } - // recursively fill from base class param block - ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults::instance().get()); - - } - const PARAM_BLOCK& get() { return mPrototype; } private: @@ -120,6 +106,7 @@ private: template class ParamDefaults : public LLSingleton > { + LLSINGLETON(ParamDefaults); public: const LLInitParam::BaseBlock& get() { return mBaseBlock; } private: @@ -297,6 +284,25 @@ private: std::vector mFileNames; }; +template +LLUICtrlFactory::ParamDefaults::ParamDefaults() +{ + // look up template file for this param block... + const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); + if (param_block_tag) + { // ...and if it exists, back fill values using the most specific template first + PARAM_BLOCK params; + LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); + mPrototype.fillFrom(params); + } + // recursively fill from base class param block + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults::instance().get()); + +} + +template +LLUICtrlFactory::ParamDefaults::ParamDefaults() {} + // this is here to make gcc happy with reference to LLUICtrlFactory template template diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 24c3a2b513..efafe543ab 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -62,9 +62,9 @@ void LLUrlRegistryNullCallback(const std::string &url, /// class LLUrlRegistry : public LLSingleton { -public: + LLSINGLETON(LLUrlRegistry); ~LLUrlRegistry(); - +public: /// add a new Url handler to the registry (will be freed on destruction) /// optionally force it to the front of the list, making it take /// priority over other regular expression matches for URLs @@ -89,9 +89,6 @@ public: bool isUrl(const LLWString &text); private: - LLUrlRegistry(); - friend class LLSingleton; - std::vector mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; LLUrlEntryBase* mUrlEntryIcon; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 62c3f401bf..2f27eebcd8 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1892,6 +1892,7 @@ private: class SortByTabOrder : public LLQuerySorter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(SortByTabOrder); /*virtual*/ void sort(LLView * parent, LLView::child_list_t &children) const { children.sort(CompareByTabOrder(parent->getTabOrder(), parent->getDefaultTabGroup())); @@ -1915,6 +1916,7 @@ const LLViewQuery & LLView::getTabOrderQuery() // This class is only used internally by getFocusRootsQuery below. class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLFocusRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h index 375efcc3de..d1059d55de 100644 --- a/indra/llui/llviewereventrecorder.h +++ b/indra/llui/llviewereventrecorder.h @@ -44,13 +44,10 @@ class LLViewerEventRecorder : public LLSingleton { - - public: - - LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton + LLSINGLETON(LLViewerEventRecorder); ~LLViewerEventRecorder(); - + public: void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName); void setMouseLocalCoords(S32 x,S32 y); void setMouseGlobalCoords(S32 x,S32 y); diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index 9044c4ff29..21bb1be26f 100644 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -54,31 +54,37 @@ public: class LLLeavesFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLLeavesFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLRootsFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLVisibleFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLVisibleFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLEnabledFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLEnabledFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLTabStopFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLTabStopFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLCtrlFilter : public LLQueryFilter, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLCtrlFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index ad2a39cab7..b356cff98c 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -41,7 +41,9 @@ class LLView; // lookup widget type by name class LLWidgetTypeRegistry : public LLRegistrySingleton -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry); +}; // global static instance for registering all widget types @@ -51,7 +53,9 @@ typedef LLRegistry widget_registry_t; class LLChildRegistryRegistry : public LLRegistrySingleton -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry); +}; class LLXSDWriter : public LLInitParam::Parser { diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp index 0cfb810906..c9ea3ed597 100644 --- a/indra/media_plugins/cef/windows_volume_catcher.cpp +++ b/indra/media_plugins/cef/windows_volume_catcher.cpp @@ -31,17 +31,16 @@ #include "llsingleton.h" class VolumeCatcherImpl : public LLSingleton { -friend LLSingleton; + LLSINGLETON(VolumeCatcherImpl); + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + ~VolumeCatcherImpl(); + public: void setVolume(F32 volume); void setPan(F32 pan); private: - // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. - VolumeCatcherImpl(); - ~VolumeCatcherImpl(); - typedef void (WINAPI *set_volume_func_t)(F32); typedef void (WINAPI *set_mute_func_t)(bool); diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h index f251ceffd4..55e1d19f05 100644 --- a/indra/newview/llaccountingcostmanager.h +++ b/indra/newview/llaccountingcostmanager.h @@ -58,9 +58,9 @@ protected: //=============================================================================== class LLAccountingCostManager : public LLSingleton { + LLSINGLETON(LLAccountingCostManager); + public: - //Ctor - LLAccountingCostManager(); //Store an object that will be eventually fetched void addObject( const LLUUID& objectID ); //Request quotas for object list diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h index abf7027ed2..f981e08ff7 100644 --- a/indra/newview/llagentpicksinfo.h +++ b/indra/newview/llagentpicksinfo.h @@ -36,14 +36,12 @@ struct LLAvatarPicks; */ class LLAgentPicksInfo : public LLSingleton { + LLSINGLETON(LLAgentPicksInfo); + virtual ~LLAgentPicksInfo(); + class LLAgentPicksObserver; public: - - LLAgentPicksInfo(); - - virtual ~LLAgentPicksInfo(); - /** * Requests number of picks from server. * diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index e01a28770e..dde041e818 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -42,9 +42,10 @@ class LLOutfitUnLockTimer; class LLAppearanceMgr: public LLSingleton { + LLSINGLETON(LLAppearanceMgr); + ~LLAppearanceMgr(); LOG_CLASS(LLAppearanceMgr); - friend class LLSingleton; friend class LLOutfitUnLockTimer; public: @@ -233,10 +234,6 @@ private: static void debugAppearanceUpdateCOF(const LLSD& content); std::string mAppearanceServiceURL; - -protected: - LLAppearanceMgr(); - ~LLAppearanceMgr(); private: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index bddc50746a..d10f8388b1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -383,6 +383,7 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; */ class LLDeferredTaskList: public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList); LOG_CLASS(LLDeferredTaskList); friend class LLAppViewer; @@ -732,7 +733,7 @@ LLAppViewer::LLAppViewer() LLAppViewer::~LLAppViewer() { delete mSettingsLocationList; - LLViewerEventRecorder::instance().~LLViewerEventRecorder(); + LLViewerEventRecorder::deleteSingleton(); LLLoginInstance::instance().setUpdaterService(0); diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h index bb7d35edbc..a4ef762e8b 100644 --- a/indra/newview/llattachmentsmgr.h +++ b/indra/newview/llattachmentsmgr.h @@ -62,6 +62,9 @@ class LLViewerInventoryItem; //-------------------------------------------------------------------------------- class LLAttachmentsMgr: public LLSingleton { + LLSINGLETON(LLAttachmentsMgr); + virtual ~LLAttachmentsMgr(); + public: // Stores info for attachments that will be requested during idle. struct AttachmentsInfo @@ -72,9 +75,6 @@ public: }; typedef std::deque attachments_vec_t; - LLAttachmentsMgr(); - virtual ~LLAttachmentsMgr(); - void addAttachmentRequest(const LLUUID& item_id, const U8 attachment_pt, const BOOL add); diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h index 9eecc2d981..23cc313646 100644 --- a/indra/newview/llautoreplace.h +++ b/indra/newview/llautoreplace.h @@ -191,6 +191,7 @@ class LLAutoReplaceSettings */ class LLAutoReplace : public LLSingleton { + LLSINGLETON(LLAutoReplace); public: /// Callback that provides the hook for use in text entry methods void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text); @@ -202,8 +203,6 @@ public: void setSettings(const LLAutoReplaceSettings& settings); private: - friend class LLSingleton; - LLAutoReplace(); /*virtual*/ void initSingleton(); LLAutoReplaceSettings mSettings; ///< configuration information diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index a6e745448a..e4f9a338f2 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -689,6 +689,8 @@ namespace action_give_inventory struct LLShareInfo : public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLShareInfo); + public: std::vector mAvatarNames; uuid_vec_t mAvatarUuids; }; diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index 5b5720f4ac..a1dacd1a27 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -37,6 +37,8 @@ class LLAvatarName; class LLAvatarIconIDCache: public LLSingleton { + LLSINGLETON(LLAvatarIconIDCache); + public: struct LLAvatarIconIDCacheItem { @@ -46,10 +48,6 @@ public: bool expired(); }; - LLAvatarIconIDCache() - : mFilename("avatar_icons_cache.txt") - {} - void load (); void save (); @@ -64,6 +62,11 @@ protected: std::map mCache;//we cache only LLUID and time }; +inline +LLAvatarIconIDCache::LLAvatarIconIDCache() + : mFilename("avatar_icons_cache.txt") +{} + namespace LLAvatarIconCtrlEnums { enum ESymbolPos diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 1dcd2c9b90..d5c5c75c69 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -187,13 +187,12 @@ public: class LLAvatarPropertiesProcessor : public LLSingleton { -public: - - LLAvatarPropertiesProcessor(); + LLSINGLETON(LLAvatarPropertiesProcessor); virtual ~LLAvatarPropertiesProcessor(); +public: void addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer); - + void removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer); // Request various types of avatar data. Duplicate requests will be diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h index 870ef4f394..6b5fa7bc35 100644 --- a/indra/newview/llavatarrenderinfoaccountant.h +++ b/indra/newview/llavatarrenderinfoaccountant.h @@ -38,13 +38,13 @@ class LLViewerRegion; // that is sent to or fetched from regions. class LLAvatarRenderInfoAccountant : public LLSingleton { + LLSINGLETON(LLAvatarRenderInfoAccountant); + ~LLAvatarRenderInfoAccountant(); + private: LOG_CLASS(LLAvatarRenderInfoAccountant); public: - LLAvatarRenderInfoAccountant(); - ~LLAvatarRenderInfoAccountant(); - void sendRenderInfoToRegion(LLViewerRegion * regionp); void getRenderInfoFromRegion(LLViewerRegion * regionp); diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h index 2a2704de28..bb82af560b 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -37,9 +37,9 @@ class LLViewerRegion; // reported that user's agent is too 'heavy' for their settings class LLAvatarRenderNotifier : public LLSingleton { -public: - LLAvatarRenderNotifier(); + LLSINGLETON(LLAvatarRenderNotifier); +public: void displayNotification(bool show_over_limit); bool isNotificationVisible(); diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index a5de8a5327..8b9d0dda8b 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -43,6 +43,9 @@ namespace LLNotificationsUI */ class LLChannelManager : public LLSingleton { + LLSINGLETON(LLChannelManager); + virtual ~LLChannelManager(); + public: @@ -65,9 +68,6 @@ public: } }; - LLChannelManager(); - virtual ~LLChannelManager(); - // On LoginCompleted - show StartUp toast void onLoginCompleted(); // removes a channel intended for the startup toast and allows other channels to show their toasts diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index 254e3f61a8..c4f959bfa9 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -38,7 +38,7 @@ namespace const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; } -LLChicletBar::LLChicletBar(const LLSD&) +LLChicletBar::LLChicletBar() : mChicletPanel(NULL), mToolbarStack(NULL) { diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h index 956c82cb77..6c521dc1d5 100644 --- a/indra/newview/llchicletbar.h +++ b/indra/newview/llchicletbar.h @@ -38,8 +38,9 @@ class LLChicletBar : public LLSingleton , public LLPanel { + LLSINGLETON(LLChicletBar); LOG_CLASS(LLChicletBar); - friend class LLSingleton; + public: BOOL postBuild(); @@ -82,8 +83,6 @@ private: void fitWithTopInfoBar(); protected: - LLChicletBar(const LLSD& key = LLSD()); - LLChicletPanel* mChicletPanel; LLLayoutStack* mToolbarStack; }; diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 62f08144b9..035cbcb945 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -109,7 +109,7 @@ private: class LLConversationLog : public LLSingleton, LLIMSessionObserver { - friend class LLSingleton; + LLSINGLETON(LLConversationLog); public: void removeConversation(const LLConversation& conversation); @@ -157,7 +157,6 @@ public: private: - LLConversationLog(); virtual ~LLConversationLog() { if (mAvatarNameCacheConnection.connected()) diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h index 3d2144960d..04db9d5dac 100644 --- a/indra/newview/lldaycyclemanager.h +++ b/indra/newview/lldaycyclemanager.h @@ -40,6 +40,7 @@ */ class LLDayCycleManager : public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLDayCycleManager); LOG_CLASS(LLDayCycleManager); public: @@ -66,7 +67,6 @@ public: boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb); private: - friend class LLSingleton; /*virtual*/ void initSingleton(); void loadAllPresets(); diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h index bf1eb62957..33f02b3521 100644 --- a/indra/newview/lldeferredsounds.h +++ b/indra/newview/lldeferredsounds.h @@ -33,7 +33,7 @@ struct SoundData; class LLDeferredSounds : public LLSingleton { -private: + LLSINGLETON_EMPTY_CTOR(LLDeferredSounds); std::vector soundVector; public: //Add sounds to be played once progress bar is hidden (such as after teleport or loading screen) diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index 7836e2cb94..7d2712eec7 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -69,8 +69,7 @@ BOOL LLDoNotDisturbNotificationStorageTimer::tick() } LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage() - : LLSingleton() - , LLNotificationStorage("") + : LLNotificationStorage("") , mDirty(false) { nameToPayloadParameterMap[toastName] = "SESSION_ID"; diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h index 6e68b0d1be..e6cb7835e3 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.h +++ b/indra/newview/lldonotdisturbnotificationstorage.h @@ -47,14 +47,14 @@ public: class LLDoNotDisturbNotificationStorage : public LLSingleton, public LLNotificationStorage { + LLSINGLETON(LLDoNotDisturbNotificationStorage); + ~LLDoNotDisturbNotificationStorage(); + LOG_CLASS(LLDoNotDisturbNotificationStorage); public: static const char * toastName; static const char * offerName; - LLDoNotDisturbNotificationStorage(); - ~LLDoNotDisturbNotificationStorage(); - void initialize(); bool getDirty(); void resetDirty(); diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index c7877303fc..6a0a267f4e 100644 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -162,14 +162,13 @@ public: */ class LLEnvManagerNew : public LLSingleton { + LLSINGLETON(LLEnvManagerNew); LOG_CLASS(LLEnvManagerNew); public: typedef boost::signals2::signal prefs_change_signal_t; typedef boost::signals2::signal region_settings_change_signal_t; typedef boost::signals2::signal region_settings_applied_signal_t; - LLEnvManagerNew(); - // getters to access user env. preferences bool getUseRegionSettings() const; bool getUseDayCycle() const; @@ -231,7 +230,6 @@ public: void onRegionSettingsApplyResponse(bool ok); private: - friend class LLSingleton; /*virtual*/ void initSingleton(); void loadUserPrefs(); diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h index fcfbd1ce7d..e7a6a2a725 100644 --- a/indra/newview/llestateinfomodel.h +++ b/indra/newview/llestateinfomodel.h @@ -38,6 +38,7 @@ class LLMessageSystem; */ class LLEstateInfoModel : public LLSingleton { + LLSINGLETON(LLEstateInfoModel); LOG_CLASS(LLEstateInfoModel); public: @@ -73,11 +74,8 @@ public: protected: typedef std::vector strings_t; - friend class LLSingleton; friend class LLDispatchEstateUpdateInfo; - LLEstateInfoModel(); - /// refresh model with data from the incoming server message void update(const strings_t& strings); diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h index ac227db336..09e0cd8821 100644 --- a/indra/newview/llexperiencelog.h +++ b/indra/newview/llexperiencelog.h @@ -33,6 +33,7 @@ class LLExperienceLog : public LLSingleton { + LLSINGLETON(LLExperienceLog); public: typedef boost::signals2::signal callback_signal_t; @@ -62,7 +63,6 @@ public: void setEventsToSave(LLSD new_events){mEventsToSave = new_events; } bool isNotExpired(std::string& date); protected: - LLExperienceLog(); void handleExperienceMessage(LLSD& message); @@ -81,7 +81,6 @@ protected: bool mNotifyNewEvent; friend class LLExperienceLogDispatchHandler; - friend class LLSingleton; }; diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h index 2a2cdb5499..7fd4070f54 100644 --- a/indra/newview/llfacebookconnect.h +++ b/indra/newview/llfacebookconnect.h @@ -43,6 +43,8 @@ class LLEventPump; */ class LLFacebookConnect : public LLSingleton { + LLSINGLETON(LLFacebookConnect); + ~LLFacebookConnect() {}; LOG_CLASS(LLFacebookConnect); public: enum EConnectionState @@ -86,10 +88,7 @@ public: void openFacebookWeb(std::string url); private: - friend class LLSingleton; - LLFacebookConnect(); - ~LLFacebookConnect() {}; std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false); EConnectionState mConnectionState; diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index b1e5edd372..cac32c7f2a 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -174,6 +174,7 @@ private: class LLFavoritesOrderStorage : public LLSingleton , public LLDestroyClass { + LLSINGLETON(LLFavoritesOrderStorage); LOG_CLASS(LLFavoritesOrderStorage); public: /** @@ -222,10 +223,6 @@ public: std::map mFavoriteNames; private: - friend class LLSingleton; - LLFavoritesOrderStorage() : mIsDirty(false), mUpdateRequired(false){ load(); } - ~LLFavoritesOrderStorage() {} - /** * Removes sort indexes for items which are not in Favorites bar for now. */ @@ -275,4 +272,10 @@ private: }; }; + +inline +LLFavoritesOrderStorage::LLFavoritesOrderStorage() : + mIsDirty(false), mUpdateRequired(false) +{ load(); } + #endif // LL_LLFAVORITESBARCTRL_H diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index c3d87cea0b..54bd07329a 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -97,20 +97,10 @@ protected: class LLFeatureManager : public LLFeatureList, public LLSingleton { -public: - LLFeatureManager() - : LLFeatureList("default"), - - mInited(FALSE), - mTableVersion(0), - mSafe(FALSE), - mGPUClass(GPU_CLASS_UNKNOWN), - mExpectedGLVersion(0.f), - mGPUSupported(FALSE) - { - } + LLSINGLETON(LLFeatureManager); ~LLFeatureManager() {cleanupFeatureTables();} +public: // initialize this by loading feature table and gpu table void init(); @@ -181,5 +171,17 @@ protected: BOOL mGPUSupported; }; +inline +LLFeatureManager::LLFeatureManager() +: LLFeatureList("default"), + + mInited(FALSE), + mTableVersion(0), + mSafe(FALSE), + mGPUClass(GPU_CLASS_UNKNOWN), + mExpectedGLVersion(0.f), + mGPUSupported(FALSE) +{ +} #endif // LL_LLFEATUREMANAGER_H diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h index 0155804da0..43cadca708 100644 --- a/indra/newview/llflickrconnect.h +++ b/indra/newview/llflickrconnect.h @@ -43,6 +43,8 @@ class LLEventPump; */ class LLFlickrConnect : public LLSingleton { + LLSINGLETON(LLFlickrConnect); + ~LLFlickrConnect() {}; LOG_CLASS(LLFlickrConnect); public: enum EConnectionState @@ -80,10 +82,7 @@ public: void openFlickrWeb(std::string url); private: - friend class LLSingleton; - LLFlickrConnect(); - ~LLFlickrConnect() {}; std::string getFlickrConnectURL(const std::string& route = "", bool include_read_from_master = false); EConnectionState mConnectionState; diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index ae3800e17b..2fb912a930 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -37,9 +37,10 @@ class LLFriendCardsManager : public LLSingleton , public LLFriendObserver { + LLSINGLETON(LLFriendCardsManager); + ~LLFriendCardsManager(); LOG_CLASS(LLFriendCardsManager); - friend class LLSingleton; friend class CreateFriendCardCallback; public: @@ -97,8 +98,6 @@ public: private: typedef boost::function callback_t; - LLFriendCardsManager(); - ~LLFriendCardsManager(); /** diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 26a5924ec3..402bdf6039 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -51,6 +51,8 @@ public: class LLGestureMgr : public LLSingleton, public LLInventoryFetchItemsObserver { + LLSINGLETON(LLGestureMgr); + ~LLGestureMgr(); public: typedef boost::function gesture_loaded_callback_t; @@ -58,8 +60,6 @@ public: typedef std::map item_map_t; typedef std::map callback_map_t; - LLGestureMgr(); - ~LLGestureMgr(); void init(); diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index e5ce768035..940ef6eea1 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -348,6 +348,8 @@ struct LLRoleActionSet class LLGroupMgr : public LLSingleton { + LLSINGLETON(LLGroupMgr); + ~LLGroupMgr(); LOG_CLASS(LLGroupMgr); public: @@ -369,8 +371,6 @@ public: public: - LLGroupMgr(); - ~LLGroupMgr(); void addObserver(LLGroupMgrObserver* observer); void addObserver(const LLUUID& group_id, LLParticularGroupObserver* observer); diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h index 9c5d49decd..7782739690 100644 --- a/indra/newview/llhudmanager.h +++ b/indra/newview/llhudmanager.h @@ -36,10 +36,10 @@ class LLMessageSystem; class LLHUDManager : public LLSingleton { -public: - LLHUDManager(); + LLSINGLETON(LLHUDManager); ~LLHUDManager(); +public: LLHUDEffect *createViewerEffect(const U8 type, BOOL send_to_sim = TRUE, BOOL originated_here = TRUE); void updateEffects(); diff --git a/indra/newview/llimagefiltersmanager.h b/indra/newview/llimagefiltersmanager.h index 4751933065..f1ed3cf1c3 100644 --- a/indra/newview/llimagefiltersmanager.h +++ b/indra/newview/llimagefiltersmanager.h @@ -34,6 +34,8 @@ class LLImageFiltersManager : public LLSingleton { + LLSINGLETON(LLImageFiltersManager); + ~LLImageFiltersManager(); LOG_CLASS(LLImageFiltersManager); public: const std::vector getFiltersList() const; @@ -43,10 +45,7 @@ private: void loadAllFilters(); void loadFiltersFromDir(const std::string& dir); - friend class LLSingleton; /*virtual*/ void initSingleton(); - LLImageFiltersManager(); - ~LLImageFiltersManager(); // List of filters : first is the user friendly localized name, second is the xml file name std::map mFiltersList; diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index d4bea1e443..da40ac8393 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -62,6 +62,7 @@ private: */ class LLIMModel : public LLSingleton { + LLSINGLETON(LLIMModel); public: struct LLIMSession : public boost::signals2::trackable @@ -152,7 +153,6 @@ public: }; - LLIMModel(); /** Session id to session object */ std::map mId2SessionMap; @@ -313,6 +313,7 @@ public: class LLIMMgr : public LLSingleton { + LLSINGLETON(LLIMMgr); friend class LLIMModel; public: @@ -323,8 +324,6 @@ public: INVITATION_TYPE_IMMEDIATE = 2 }; - LLIMMgr(); - virtual ~LLIMMgr() {}; // Add a message to a session. The session can keyed to sesion id // or agent id. diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 013a5a7629..495180f087 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -46,8 +46,7 @@ struct IconEntry : public LLDictionaryEntry class LLIconDictionary : public LLSingleton, public LLDictionary { -public: - LLIconDictionary(); + LLSINGLETON(LLIconDictionary); }; typedef LLPointer LLUIImagePtr; diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 19fbfc2ed3..00d2908c1b 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -43,9 +43,9 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLInventoryModelBackgroundFetch : public LLSingleton { -public: - LLInventoryModelBackgroundFetch(); + LLSINGLETON(LLInventoryModelBackgroundFetch); ~LLInventoryModelBackgroundFetch(); +public: // Start and stop background breadth-first fetching of inventory contents. // This gets triggered when performing a filter-search. diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h index 9fef42c5df..1cecbabd3b 100644 --- a/indra/newview/lllocationhistory.h +++ b/indra/newview/lllocationhistory.h @@ -103,6 +103,7 @@ public: class LLLocationHistory: public LLSingleton { + LLSINGLETON(LLLocationHistory); LOG_CLASS(LLLocationHistory); public: @@ -117,7 +118,6 @@ public: typedef boost::function history_changed_callback_t; typedef boost::signals2::signal history_changed_signal_t; - LLLocationHistory(); void addItem(const LLLocationHistoryItem& item); bool touchItem(const LLLocationHistoryItem& item); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 639641d1c2..00c029d79b 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -132,15 +132,9 @@ void append_to_last_message(std::list& messages, const std::string& line) class LLLogChatTimeScanner: public LLSingleton { -public: - LLLogChatTimeScanner() - { - // Note, date/time facets will be destroyed by string streams - mDateStream.imbue(std::locale(mDateStream.getloc(), new date_input_facet(DATE_FORMAT))); - mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_facet(TIME_FORMAT))); - mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_input_facet(DATE_FORMAT))); - } + LLSINGLETON(LLLogChatTimeScanner); +public: date getTodayPacificDate() { typedef boost::date_time::local_adjustor pst; @@ -205,6 +199,15 @@ private: std::stringstream mTimeStream; }; +inline +LLLogChatTimeScanner::LLLogChatTimeScanner() +{ + // Note, date/time facets will be destroyed by string streams + mDateStream.imbue(std::locale(mDateStream.getloc(), new date_input_facet(DATE_FORMAT))); + mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_facet(TIME_FORMAT))); + mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_input_facet(DATE_FORMAT))); +} + LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL; std::map LLLogChat::sLoadHistoryThreads; diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index c6773bbf68..282ddc1cea 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -40,12 +40,12 @@ class LLUpdaterService; // negotiate user authentication attempts. class LLLoginInstance : public LLSingleton { + LLSINGLETON(LLLoginInstance); + ~LLLoginInstance(); + public: class Disposable; - LLLoginInstance(); - ~LLLoginInstance(); - void connect(LLPointer credentials); // Connect to the current grid choice. void connect(const std::string& uri, LLPointer credentials); // Connect to the given uri. void reconnect(); // reconnect using the current credentials. diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h index f84c0ca94c..2ec3a74e4a 100644 --- a/indra/newview/llmainlooprepeater.h +++ b/indra/newview/llmainlooprepeater.h @@ -43,9 +43,8 @@ class LLMainLoopRepeater: public LLSingleton { + LLSINGLETON(LLMainLoopRepeater); public: - LLMainLoopRepeater(void); - // Start the repeater service. void start(void); diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 9d795c6ced..ec312baca3 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -86,11 +86,10 @@ namespace MarketplaceFetchCodes class LLMarketplaceInventoryImporter : public LLSingleton { + LLSINGLETON(LLMarketplaceInventoryImporter); public: static void update(); - - LLMarketplaceInventoryImporter(); - + typedef boost::signals2::signal status_changed_signal_t; typedef boost::signals2::signal status_report_signal_t; @@ -181,10 +180,11 @@ class LLSLMDeleteListingsResponder; class LLMarketplaceData : public LLSingleton { - friend class LLSingleton < LLMarketplaceData > ; + LLSINGLETON(LLMarketplaceData); + virtual ~LLMarketplaceData(); public: - friend class LLSLMGetMerchantResponder; + friend class LLSLMGetMerchantResponder; friend class LLSLMGetListingsResponder; friend class LLSLMCreateListingsResponder; friend class LLSLMGetListingResponder; @@ -242,9 +242,6 @@ public: void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1); private: - LLMarketplaceData(); - virtual ~LLMarketplaceData(); - // Modify Marketplace data set : each method returns true if the function succeeds, false if error // Used internally only by SLM Responders when data are received from the SLM Server bool addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed, const std::string& edit_url, S32 count); diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 36dd0904b6..60b58d17de 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -38,9 +38,7 @@ class LLViewerRegion; class LLMaterialMgr : public LLSingleton { - friend class LLSingleton; -protected: - LLMaterialMgr(); + LLSINGLETON(LLMaterialMgr); virtual ~LLMaterialMgr(); public: diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp index 8879cfd7fb..63d97f6ac2 100644 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -41,8 +41,7 @@ #include "llpathfindingnavmeshstatus.h" #include "llviewerregion.h" -LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() - : LLSingleton(), +LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() : mIsInitialized(false), mCanRebakeRegion(false), mRebakeNavMeshMode(kRebakeNavMesh_Default), diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h index 7b1d2873ba..649a387dd3 100644 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h @@ -37,6 +37,8 @@ class LLPathfindingNavMeshStatus; class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton { + LLSINGLETON(LLMenuOptionPathfindingRebakeNavmesh); + virtual ~LLMenuOptionPathfindingRebakeNavmesh(); LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh); public: @@ -49,8 +51,6 @@ public: kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable } ERebakeNavMeshMode; - LLMenuOptionPathfindingRebakeNavmesh(); - virtual ~LLMenuOptionPathfindingRebakeNavmesh(); void initialize(); void quit(); diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 63d1a81ca6..4ceddc97fd 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -71,6 +71,8 @@ public: class LLMuteList : public LLSingleton { + LLSINGLETON(LLMuteList); + ~LLMuteList(); public: // reasons for auto-unmuting a resident enum EAutoReason @@ -81,8 +83,6 @@ public: AR_COUNT // enum count }; - LLMuteList(); - ~LLMuteList(); void addObserver(LLMuteListObserver* observer); void removeObserver(LLMuteListObserver* observer); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 3f74c9d51b..a44c6dd699 100755 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -85,12 +85,12 @@ protected: class LLNavigationBar : public LLPanel, public LLSingleton, private LLDestroyClass { + LLSINGLETON(LLNavigationBar); + virtual ~LLNavigationBar(); LOG_CLASS(LLNavigationBar); friend class LLDestroyClass; - + public: - LLNavigationBar(); - virtual ~LLNavigationBar(); /*virtual*/ void draw(); /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index f37c6b833c..52c79cc689 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -46,11 +46,11 @@ class LLToast; */ class LLNotificationManager : public LLSingleton { - typedef std::pair eventhandlers; -public: - LLNotificationManager(); + LLSINGLETON(LLNotificationManager); virtual ~LLNotificationManager(); + typedef std::pair eventhandlers; +public: //TODO: make private // this method initialize handlers' map for different types of notifications void init(void); diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp index 3418b33d37..35fdfa88bb 100644 --- a/indra/newview/llnotificationstorage.cpp +++ b/indra/newview/llnotificationstorage.cpp @@ -45,9 +45,10 @@ typedef boost::function { - public: - template static LLNotificationResponderInterface * create(const LLSD& pParams); - LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams); + LLSINGLETON_EMPTY_CTOR(LLResponderRegistry); +public: + template static LLNotificationResponderInterface * create(const LLSD& pParams); + LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams); }; template LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams) diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h index 87d4b0c998..77041db68d 100644 --- a/indra/newview/lloutfitobserver.h +++ b/indra/newview/lloutfitobserver.h @@ -36,10 +36,10 @@ */ class LLOutfitObserver: public LLInventoryObserver, public LLSingleton { -public: + LLSINGLETON(LLOutfitObserver); virtual ~LLOutfitObserver(); - friend class LLSingleton; +public: virtual void changed(U32 mask); @@ -58,7 +58,6 @@ public: void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); } protected: - LLOutfitObserver(); /** Get a version of an inventory category specified by its UUID */ static S32 getCategoryVersion(const LLUUID& cat_id); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index b7e1b2d3a4..f2d43a1037 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -117,8 +117,7 @@ class LLEditWearableDictionary : public LLSingleton //-------------------------------------------------------------------- // Constructors and Destructors //-------------------------------------------------------------------- -public: - LLEditWearableDictionary(); + LLSINGLETON(LLEditWearableDictionary); virtual ~LLEditWearableDictionary(); //-------------------------------------------------------------------- diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 3de9dc2f80..fe0608d544 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -104,7 +104,9 @@ private: //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -class LLTeleportHistoryFlatItemStorage: public LLSingleton { +class LLTeleportHistoryFlatItemStorage: public LLSingleton +{ + LLSINGLETON_EMPTY_CTOR(LLTeleportHistoryFlatItemStorage); protected: typedef std::vector< LLHandle > flat_item_list_t; diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h index 274d70c6f9..78dd997029 100644 --- a/indra/newview/llpaneltopinfobar.h +++ b/indra/newview/llpaneltopinfobar.h @@ -37,6 +37,8 @@ class LLParcelChangeObserver; class LLPanelTopInfoBar : public LLPanel, public LLSingleton, private LLDestroyClass { + LLSINGLETON(LLPanelTopInfoBar); + ~LLPanelTopInfoBar(); LOG_CLASS(LLPanelTopInfoBar); friend class LLDestroyClass; @@ -44,9 +46,6 @@ class LLPanelTopInfoBar : public LLPanel, public LLSingleton, public: typedef boost::signals2::signal resize_signal_t; - LLPanelTopInfoBar(); - ~LLPanelTopInfoBar(); - /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index 711a869e82..cb4c07a417 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -144,8 +144,7 @@ typedef boost::shared_ptr LinksetsResponderPtr; // LLPathfindingManager //--------------------------------------------------------------------------- -LLPathfindingManager::LLPathfindingManager() - : LLSingleton(), +LLPathfindingManager::LLPathfindingManager(): mNavMeshMap(), mAgentStateSignal() { diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h index e8fad590ba..a44cd892da 100644 --- a/indra/newview/llpathfindingmanager.h +++ b/indra/newview/llpathfindingmanager.h @@ -48,6 +48,9 @@ class LinksetsResponder; class LLPathfindingManager : public LLSingleton { + LLSINGLETON(LLPathfindingManager); + virtual ~LLPathfindingManager(); + friend class LLNavMeshSimStateChangeNode; friend class NavMeshStatusResponder; friend class LLAgentStateChangeNode; @@ -60,9 +63,6 @@ public: kRequestError } ERequestStatus; - LLPathfindingManager(); - virtual ~LLPathfindingManager(); - void initSystem(); void quitSystem(); diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp index 006755e20b..3187325101 100644 --- a/indra/newview/llpathfindingpathtool.cpp +++ b/indra/newview/llpathfindingpathtool.cpp @@ -46,7 +46,6 @@ LLPathfindingPathTool::LLPathfindingPathTool() : LLTool(PATH_TOOL_NAME), - LLSingleton(), mFinalPathData(), mTempPathData(), mPathResult(LLPathingLib::LLPL_NO_PATH), diff --git a/indra/newview/llpathfindingpathtool.h b/indra/newview/llpathfindingpathtool.h index 97284265f1..88cb3a15f8 100644 --- a/indra/newview/llpathfindingpathtool.h +++ b/indra/newview/llpathfindingpathtool.h @@ -36,6 +36,9 @@ class LLPathfindingPathTool : public LLTool, public LLSingleton { + LLSINGLETON(LLPathfindingPathTool); + virtual ~LLPathfindingPathTool(); + public: typedef enum { @@ -59,9 +62,6 @@ public: kCharacterTypeD } ECharacterType; - LLPathfindingPathTool(); - virtual ~LLPathfindingPathTool(); - typedef boost::function path_event_callback_t; typedef boost::signals2::signal path_event_signal_t; typedef boost::signals2::connection path_event_slot_t; diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 9c0222d0bc..264382ae82 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -36,9 +36,8 @@ #include "llscriptfloater.h" #include "llviewermessage.h" #include "llviewernetwork.h" -LLPersistentNotificationStorage::LLPersistentNotificationStorage() - : LLSingleton() - , LLNotificationStorage("") +LLPersistentNotificationStorage::LLPersistentNotificationStorage(): + LLNotificationStorage("") , mLoaded(false) { } diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index bf0306380e..40c9923c74 100644 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -45,10 +45,10 @@ class LLSD; class LLPersistentNotificationStorage : public LLSingleton, public LLNotificationStorage { + LLSINGLETON(LLPersistentNotificationStorage); + ~LLPersistentNotificationStorage(); LOG_CLASS(LLPersistentNotificationStorage); public: - LLPersistentNotificationStorage(); - ~LLPersistentNotificationStorage(); void saveNotifications(); void loadNotifications(); diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h index 21f9885f27..0014e32267 100644 --- a/indra/newview/llpresetsmanager.h +++ b/indra/newview/llpresetsmanager.h @@ -46,6 +46,9 @@ enum EDefaultOptions class LLPresetsManager : public LLSingleton { + LLSINGLETON(LLPresetsManager); + ~LLPresetsManager(); + public: typedef std::list preset_name_list_t; @@ -67,9 +70,6 @@ public: preset_name_list_t mPresetNames; - LLPresetsManager(); - ~LLPresetsManager(); - preset_list_signal_t mPresetListChangeSignal; private: diff --git a/indra/newview/llproductinforequest.h b/indra/newview/llproductinforequest.h index 75dbf220d1..d1036374e8 100644 --- a/indra/newview/llproductinforequest.h +++ b/indra/newview/llproductinforequest.h @@ -41,12 +41,11 @@ */ class LLProductInfoRequestManager : public LLSingleton { + LLSINGLETON(LLProductInfoRequestManager); public: - LLProductInfoRequestManager(); std::string getDescriptionForSku(const std::string& sku); private: - friend class LLSingleton; /* virtual */ void initSingleton(); void getLandDescriptionsCoro(std::string url); diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index d0d6376867..c7aaf604f5 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -50,6 +50,7 @@ class LLDate; */ class LLRecentPeople: public LLSingleton, public LLOldEvents::LLSimpleListener { + LLSINGLETON_EMPTY_CTOR(LLRecentPeople); LOG_CLASS(LLRecentPeople); public: typedef boost::signals2::signal signal_t; diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h index d22a0de463..ea9640efda 100644 --- a/indra/newview/llregioninfomodel.h +++ b/indra/newview/llregioninfomodel.h @@ -36,6 +36,7 @@ class LLMessageSystem; */ class LLRegionInfoModel : public LLSingleton { + LLSINGLETON(LLRegionInfoModel); LOG_CLASS(LLRegionInfoModel); public: @@ -73,10 +74,8 @@ public: std::string mSimType; protected: - friend class LLSingleton; friend class LLViewerRegion; - LLRegionInfoModel(); /** * Refresh model with data from the incoming server message. diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index cb5af50c5f..5b0d189137 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -74,9 +74,10 @@ protected: class LLRemoteParcelInfoProcessor : public LLSingleton { -public: + LLSINGLETON_EMPTY_CTOR(LLRemoteParcelInfoProcessor); virtual ~LLRemoteParcelInfoProcessor() {} +public: void addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer); void removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer); diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h index 5223a314f3..2ac958e7b8 100644 --- a/indra/newview/llrootview.h +++ b/indra/newview/llrootview.h @@ -32,7 +32,9 @@ #include "lltooltip.h" class LLRootViewRegistry : public LLChildRegistry -{}; +{ + LLSINGLETON(LLRootViewRegistry); +}; class LLRootView : public LLView { diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 2b6ea57b96..7cd531bd34 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -39,10 +39,10 @@ class LLViewerTexture; class LLSceneMonitor : public LLSingleton { + LLSINGLETON(LLSceneMonitor); + ~LLSceneMonitor(); LOG_CLASS(LLSceneMonitor); public: - LLSceneMonitor(); - ~LLSceneMonitor(); void freezeAvatar(LLCharacter* avatarp); void setDebugViewerVisible(bool visible); diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h index 70451194b3..c0b84abdcb 100644 --- a/indra/newview/llscriptfloater.h +++ b/indra/newview/llscriptfloater.h @@ -41,6 +41,7 @@ class LLScriptFloaterManager : public LLSingleton // *TODO // LLScriptFloaterManager and LLScriptFloater will need some refactoring after we // know how script notifications should look like. + LLSINGLETON_EMPTY_CTOR(LLScriptFloaterManager); public: typedef enum e_object_type diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h index ade81675c2..5aab5e6765 100644 --- a/indra/newview/llsearchhistory.h +++ b/indra/newview/llsearchhistory.h @@ -37,6 +37,7 @@ */ class LLSearchHistory : public LLSingleton, private LLDestroyClass { + LLSINGLETON(LLSearchHistory); friend class LLDestroyClass; public: @@ -72,7 +73,6 @@ public: */ void addEntry(const std::string& search_text); - LLSearchHistory(); /** * Class for storing data about single search request. diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index bc50e443f8..c167ecd236 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -388,6 +388,9 @@ struct LLSelectGetFirstTest; class LLSelectMgr : public LLEditMenuHandler, public LLSingleton { + LLSINGLETON(LLSelectMgr); + ~LLSelectMgr(); + public: static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded? @@ -413,9 +416,6 @@ public: LLCachedControl mDebugSelectMgr; public: - LLSelectMgr(); - ~LLSelectMgr(); - static void cleanupGlobals(); // LLEditMenuHandler interface diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 5cff70f377..617bae3984 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -341,20 +341,18 @@ protected: class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton { + LLSINGLETON(LLActiveSpeakerMgr); LOG_CLASS(LLActiveSpeakerMgr); -public: - LLActiveSpeakerMgr(); protected: virtual void updateSpeakerList(); }; class LLLocalSpeakerMgr : public LLSpeakerMgr, public LLSingleton { - LOG_CLASS(LLLocalSpeakerMgr); -public: - LLLocalSpeakerMgr(); + LLSINGLETON(LLLocalSpeakerMgr); ~LLLocalSpeakerMgr (); + LOG_CLASS(LLLocalSpeakerMgr); protected: virtual void updateSpeakerList(); }; diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index 78fe7863c8..5ca1d4b4a5 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -48,6 +48,8 @@ */ class SpeakingIndicatorManager : public LLSingleton, LLVoiceClientParticipantObserver { + LLSINGLETON(SpeakingIndicatorManager); + ~SpeakingIndicatorManager(); LOG_CLASS(SpeakingIndicatorManager); public: @@ -91,10 +93,6 @@ private: typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator; typedef std::pair indicator_range_t; - friend class LLSingleton; - SpeakingIndicatorManager(); - ~SpeakingIndicatorManager(); - /** * Callback to determine when voice channel is changed. * diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h index 8aa0af535c..96b3920593 100644 --- a/indra/newview/llstylemap.h +++ b/indra/newview/llstylemap.h @@ -39,6 +39,7 @@ typedef std::map style_map_t; class LLStyleMap : public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLStyleMap); public: // Just like the [] accessor but it will add the entry in if it doesn't exist. const LLStyle::Params &lookupAgent(const LLUUID &source); diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h index 0afa6dc04b..1360b3e042 100644 --- a/indra/newview/llsyntaxid.h +++ b/indra/newview/llsyntaxid.h @@ -38,9 +38,9 @@ class fetchKeywordsFileResponder; class LLSyntaxIdLSL : public LLSingleton { - friend class LLSingleton; + LLSINGLETON(LLSyntaxIdLSL); friend class fetchKeywordsFileResponder; - + private: std::set mInflightFetches; typedef boost::signals2::signal syntax_id_changed_signal_t; @@ -67,7 +67,6 @@ private: LLSD mKeywordsXml; public: - LLSyntaxIdLSL(); void initialize(); bool keywordFetchInProgress(); LLSD getKeywordsXML() const { return mKeywordsXml; }; diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h index e9c29c39bf..db0ccdda59 100644 --- a/indra/newview/llteleporthistory.h +++ b/indra/newview/llteleporthistory.h @@ -73,6 +73,8 @@ public: */ class LLTeleportHistory: public LLSingleton { + LLSINGLETON(LLTeleportHistory); + ~LLTeleportHistory(); LOG_CLASS(LLTeleportHistory); public: @@ -81,9 +83,6 @@ public: typedef boost::function history_callback_t; typedef boost::signals2::signal history_signal_t; - LLTeleportHistory(); - ~LLTeleportHistory(); - /** * Go back in the history. */ diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h index cf4c85a991..946ac0af1a 100644 --- a/indra/newview/llteleporthistorystorage.h +++ b/indra/newview/llteleporthistorystorage.h @@ -68,6 +68,8 @@ public: */ class LLTeleportHistoryStorage: public LLSingleton { + LLSINGLETON(LLTeleportHistoryStorage); + ~LLTeleportHistoryStorage(); LOG_CLASS(LLTeleportHistoryStorage); public: @@ -78,9 +80,6 @@ public: typedef boost::function history_callback_t; typedef boost::signals2::signal history_signal_t; - LLTeleportHistoryStorage(); - ~LLTeleportHistoryStorage(); - /** * @return history items. */ diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h index b643056198..1b8df708c6 100644 --- a/indra/newview/lltextureatlasmanager.h +++ b/indra/newview/lltextureatlasmanager.h @@ -85,12 +85,11 @@ private: class LLTextureAtlasManager : public LLSingleton { -private: + LLSINGLETON(LLTextureAtlasManager); + ~LLTextureAtlasManager(); typedef std::list > ll_texture_atlas_list_t ; public: - LLTextureAtlasManager(); - ~LLTextureAtlasManager(); LLPointer reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, LLSpatialGroup* groupp, LLViewerTexture* imagep) ; diff --git a/indra/newview/lltoolbrush.h b/indra/newview/lltoolbrush.h index 2ec6911de9..c108d83256 100644 --- a/indra/newview/lltoolbrush.h +++ b/indra/newview/lltoolbrush.h @@ -43,10 +43,10 @@ class LLViewerRegion; class LLToolBrushLand : public LLTool, public LLEditMenuHandler, public LLSingleton { + LLSINGLETON(LLToolBrushLand); typedef std::set region_list_t; public: - LLToolBrushLand(); // x,y in window coords, 0,0 = left,bot virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 2b4fa757f6..d9adec82b4 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -683,7 +683,7 @@ LLToolCompGun::LLToolCompGun() : LLToolComposite(std::string("Mouselook")) { mGun = new LLToolGun(this); - mGrab = new LLToolGrab(this); + mGrab = new LLToolGrabBase(this); mNull = sNullTool; setCurrentTool(mGun); diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h index e75d3c22e2..86506f725e 100644 --- a/indra/newview/lltoolcomp.h +++ b/indra/newview/lltoolcomp.h @@ -103,9 +103,9 @@ public: class LLToolCompInspect : public LLToolComposite, public LLSingleton { -public: - LLToolCompInspect(); + LLSINGLETON(LLToolCompInspect); virtual ~LLToolCompInspect(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -128,9 +128,9 @@ private: class LLToolCompTranslate : public LLToolComposite, public LLSingleton { -public: - LLToolCompTranslate(); + LLSINGLETON(LLToolCompTranslate); virtual ~LLToolCompTranslate(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -149,9 +149,9 @@ public: class LLToolCompScale : public LLToolComposite, public LLSingleton { -public: - LLToolCompScale(); + LLSINGLETON(LLToolCompScale); virtual ~LLToolCompScale(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -171,9 +171,9 @@ public: class LLToolCompRotate : public LLToolComposite, public LLSingleton { -public: - LLToolCompRotate(); + LLSINGLETON(LLToolCompRotate); virtual ~LLToolCompRotate(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -194,9 +194,9 @@ protected: class LLToolCompCreate : public LLToolComposite, public LLSingleton { -public: - LLToolCompCreate(); + LLSINGLETON(LLToolCompCreate); virtual ~LLToolCompCreate(); +public: // Overridden from LLToolComposite virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -214,14 +214,14 @@ protected: // LLToolCompGun class LLToolGun; -class LLToolGrab; +class LLToolGrabBase; class LLToolSelect; class LLToolCompGun : public LLToolComposite, public LLSingleton { -public: - LLToolCompGun(); + LLSINGLETON(LLToolCompGun); virtual ~LLToolCompGun(); +public: // Overridden from LLToolComposite virtual BOOL handleHover(S32 x, S32 y, MASK mask); @@ -237,7 +237,7 @@ public: protected: LLToolGun* mGun; - LLToolGrab* mGrab; + LLToolGrabBase* mGrab; LLTool* mNull; }; diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 63be1ef09b..766046785b 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -43,11 +43,10 @@ class LLPickInfo; class LLToolDragAndDrop : public LLTool, public LLSingleton { + LLSINGLETON(LLToolDragAndDrop); public: typedef boost::signals2::signal enddrag_signal_t; - LLToolDragAndDrop(); - // overridden from LLTool virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); @@ -281,8 +280,8 @@ private: class LLDragAndDropDictionary : public LLSingleton, public LLDictionary { + LLSINGLETON(LLDragAndDropDictionary); public: - LLDragAndDropDictionary(); dragOrDrop3dImpl get(EDragAndDropType dad_type, EDropTarget drop_target); }; }; diff --git a/indra/newview/lltoolface.h b/indra/newview/lltoolface.h index 7eb13b0fbc..e4b8ae12b8 100644 --- a/indra/newview/lltoolface.h +++ b/indra/newview/lltoolface.h @@ -35,9 +35,9 @@ class LLPickInfo; class LLToolFace : public LLTool, public LLSingleton { -public: - LLToolFace(); + LLSINGLETON(LLToolFace); virtual ~LLToolFace(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index d23eb2cce6..cfc235b6c2 100644 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -34,9 +34,9 @@ class LLPickInfo; class LLToolCamera : public LLTool, public LLSingleton { -public: - LLToolCamera(); + LLSINGLETON(LLToolCamera); virtual ~LLToolCamera(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index c0ca4d7a9a..ed32e584a5 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -69,7 +69,7 @@ extern BOOL gDebugClicks; // // Methods // -LLToolGrab::LLToolGrab( LLToolComposite* composite ) +LLToolGrabBase::LLToolGrabBase( LLToolComposite* composite ) : LLTool( std::string("Grab"), composite ), mMode( GRAB_INACTIVE ), mVerticalDragging( FALSE ), @@ -88,12 +88,12 @@ LLToolGrab::LLToolGrab( LLToolComposite* composite ) mHideBuildHighlight(FALSE) { } -LLToolGrab::~LLToolGrab() +LLToolGrabBase::~LLToolGrabBase() { } // virtual -void LLToolGrab::handleSelect() +void LLToolGrabBase::handleSelect() { if(gFloaterTools) { @@ -106,7 +106,7 @@ void LLToolGrab::handleSelect() gGrabBtnSpin = FALSE; } -void LLToolGrab::handleDeselect() +void LLToolGrabBase::handleDeselect() { if( hasMouseCapture() ) { @@ -123,7 +123,7 @@ void LLToolGrab::handleDeselect() } -BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleDoubleClick(S32 x, S32 y, MASK mask) { if (gDebugClicks) { @@ -133,7 +133,7 @@ BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask) return FALSE; } -BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) { if (gDebugClicks) { @@ -152,7 +152,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } -void LLToolGrab::pickCallback(const LLPickInfo& pick_info) +void LLToolGrabBase::pickCallback(const LLPickInfo& pick_info) { LLToolGrab::getInstance()->mGrabPick = pick_info; LLViewerObject *objectp = pick_info.getObject(); @@ -182,7 +182,7 @@ void LLToolGrab::pickCallback(const LLPickInfo& pick_info) } } -BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) +BOOL LLToolGrabBase::handleObjectHit(const LLPickInfo& info) { mGrabPick = info; LLViewerObject* objectp = mGrabPick.getObject(); @@ -315,7 +315,7 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) } -void LLToolGrab::startSpin() +void LLToolGrabBase::startSpin() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -339,7 +339,7 @@ void LLToolGrab::startSpin() } -void LLToolGrab::stopSpin() +void LLToolGrabBase::stopSpin() { mSpinGrabbing = FALSE; @@ -373,7 +373,7 @@ void LLToolGrab::stopSpin() } -void LLToolGrab::startGrab() +void LLToolGrabBase::startGrab() { // Compute grab_offset in the OBJECT's root's coordinate frame // (sometimes root == object) @@ -422,7 +422,7 @@ void LLToolGrab::startGrab() } -BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleHover(S32 x, S32 y, MASK mask) { if (!gViewerWindow->getLeftMouseDown()) { @@ -466,7 +466,7 @@ const F32 GRAB_SENSITIVITY_Y = 0.0075f; // Dragging. -void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp || !hasMouseCapture() ) return; @@ -724,7 +724,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) } -void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverNonPhysical(S32 x, S32 y, MASK mask) { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp || !hasMouseCapture() ) return; @@ -881,7 +881,7 @@ void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) // Not dragging. Just showing affordances -void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverInactive(S32 x, S32 y, MASK mask) { // JC - TODO - change cursor based on gGrabBtnVertical, gGrabBtnSpin LL_DEBUGS("UserInput") << "hover handled by LLToolGrab (inactive-not over editable object)" << LL_ENDL; @@ -889,7 +889,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) } // User is trying to do something that's not allowed. -void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask) +void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask) { if( GRAB_NOOBJECT == mMode ) { @@ -930,7 +930,7 @@ void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask) -BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask) { // call the base class to propogate info to sim LLTool::handleMouseUp(x, y, mask); @@ -961,7 +961,7 @@ BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } -void LLToolGrab::stopEditing() +void LLToolGrabBase::stopEditing() { if( hasMouseCapture() ) { @@ -969,7 +969,7 @@ void LLToolGrab::stopEditing() } } -void LLToolGrab::onMouseCaptureLost() +void LLToolGrabBase::onMouseCaptureLost() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -1026,7 +1026,7 @@ void LLToolGrab::onMouseCaptureLost() } -void LLToolGrab::stopGrab() +void LLToolGrabBase::stopGrab() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -1067,29 +1067,29 @@ void LLToolGrab::stopGrab() } -void LLToolGrab::draw() +void LLToolGrabBase::draw() { } -void LLToolGrab::render() +void LLToolGrabBase::render() { } -BOOL LLToolGrab::isEditing() +BOOL LLToolGrabBase::isEditing() { return (mGrabPick.getObject().notNull()); } -LLViewerObject* LLToolGrab::getEditingObject() +LLViewerObject* LLToolGrabBase::getEditingObject() { return mGrabPick.getObject(); } -LLVector3d LLToolGrab::getEditingPointGlobal() +LLVector3d LLToolGrabBase::getEditingPointGlobal() { return getGrabPointGlobal(); } -LLVector3d LLToolGrab::getGrabPointGlobal() +LLVector3d LLToolGrabBase::getGrabPointGlobal() { switch(mMode) { diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 5d24c8813e..02ed5c26d7 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -45,12 +45,17 @@ void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, co void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick); - -class LLToolGrab : public LLTool, public LLSingleton +/** + * LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that + * LLToolGrab is an LLSingleton, but we also explicitly instantiate + * LLToolGrabBase as part of LLToolCompGun. You can't just make an extra + * instance of an LLSingleton! + */ +class LLToolGrabBase : public LLTool { public: - LLToolGrab( LLToolComposite* composite = NULL ); - ~LLToolGrab(); + LLToolGrabBase(LLToolComposite* composite=NULL); + ~LLToolGrabBase(); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -140,10 +145,14 @@ private: BOOL mClickedInMouselook; }; +/// This is the LLSingleton instance of LLToolGrab. +class LLToolGrab : public LLToolGrabBase, public LLSingleton +{ + LLSINGLETON_EMPTY_CTOR(LLToolGrab); +}; + extern BOOL gGrabBtnVertical; extern BOOL gGrabBtnSpin; extern LLTool* gGrabTransientTool; #endif // LL_TOOLGRAB_H - - diff --git a/indra/newview/lltoolindividual.h b/indra/newview/lltoolindividual.h index 961a6a4d93..e7c2060fba 100644 --- a/indra/newview/lltoolindividual.h +++ b/indra/newview/lltoolindividual.h @@ -39,9 +39,9 @@ class LLPickInfo; class LLToolIndividual : public LLTool, public LLSingleton { -public: - LLToolIndividual(); + LLSINGLETON(LLToolIndividual); virtual ~LLToolIndividual(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h index e5b45750d9..28465d5d2c 100644 --- a/indra/newview/lltoolmgr.h +++ b/indra/newview/lltoolmgr.h @@ -42,9 +42,9 @@ const MASK MASK_COPY = MASK_SHIFT; class LLToolMgr : public LLSingleton { -public: - LLToolMgr(); + LLSINGLETON(LLToolMgr); ~LLToolMgr(); +public: // Must be called after gSavedSettings set up. void initTools(); diff --git a/indra/newview/lltoolobjpicker.h b/indra/newview/lltoolobjpicker.h index 0c37be1f92..5ad9b67e21 100644 --- a/indra/newview/lltoolobjpicker.h +++ b/indra/newview/lltoolobjpicker.h @@ -35,8 +35,8 @@ class LLPickInfo; class LLToolObjPicker : public LLTool, public LLSingleton { + LLSINGLETON(LLToolObjPicker); public: - LLToolObjPicker(); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 6391e675c5..95d155a474 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -37,9 +37,9 @@ class LLObjectSelection; class LLToolPie : public LLTool, public LLSingleton { + LLSINGLETON(LLToolPie); LOG_CLASS(LLToolPie); public: - LLToolPie( ); // Virtual functions inherited from LLMouseHandler virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index 8a83bf31af..7575d8ad18 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -43,10 +43,10 @@ class LLPickInfo; class LLToolPipette : public LLTool, public LLSingleton { -public: - LLToolPipette(); + LLSINGLETON(LLToolPipette); virtual ~LLToolPipette(); +public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolselectland.h b/indra/newview/lltoolselectland.h index b368a4b153..b5ba72f16d 100644 --- a/indra/newview/lltoolselectland.h +++ b/indra/newview/lltoolselectland.h @@ -35,10 +35,10 @@ class LLParcelSelection; class LLToolSelectLand : public LLTool, public LLSingleton { -public: - LLToolSelectLand( ); + LLSINGLETON(LLToolSelectLand); virtual ~LLToolSelectLand(); +public: /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h index b4611c8c87..d126543f15 100644 --- a/indra/newview/lltransientfloatermgr.h +++ b/indra/newview/lltransientfloatermgr.h @@ -38,9 +38,7 @@ class LLTransientFloater; */ class LLTransientFloaterMgr: public LLSingleton { -protected: - LLTransientFloaterMgr(); - friend class LLSingleton; + LLSINGLETON(LLTransientFloaterMgr); public: enum ETransientGroup diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h index be481a17c1..e77048cc35 100644 --- a/indra/newview/lltwitterconnect.h +++ b/indra/newview/lltwitterconnect.h @@ -43,6 +43,7 @@ class LLEventPump; */ class LLTwitterConnect : public LLSingleton { + LLSINGLETON(LLTwitterConnect); LOG_CLASS(LLTwitterConnect); public: enum EConnectionState @@ -81,10 +82,7 @@ public: void openTwitterWeb(std::string url); private: - friend class LLSingleton; - LLTwitterConnect(); - ~LLTwitterConnect() {}; std::string getTwitterConnectURL(const std::string& route = "", bool include_read_from_master = false); EConnectionState mConnectionState; diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 08ba5a5f25..ad0c1734f9 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -48,8 +48,7 @@ struct ViewerAssetEntry : public LLDictionaryEntry class LLViewerAssetDictionary : public LLSingleton, public LLDictionary { -public: - LLViewerAssetDictionary(); + LLSINGLETON(LLViewerAssetDictionary); }; LLViewerAssetDictionary::LLViewerAssetDictionary() diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index 8c302c6549..16f9b63113 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -43,6 +43,9 @@ void audio_update_wind(bool force_update = true); class LLViewerAudio : public LLSingleton { + LLSINGLETON(LLViewerAudio); + virtual ~LLViewerAudio(); + public: enum EFadeState @@ -52,9 +55,6 @@ public: FADE_OUT, }; - LLViewerAudio(); - virtual ~LLViewerAudio(); - void startInternetStreamWithAutoFade(std::string streamURI); void stopInternetStreamWithAutoFade(); diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 7b2887d725..f8c973690a 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -54,6 +54,7 @@ extern template class LLViewerCamera* LLSingleton::getInst LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton { + LLSINGLETON(LLViewerCamera); public: void* operator new(size_t size) { @@ -82,8 +83,6 @@ public: static eCameraID sCurCameraID; - LLViewerCamera(); - void updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index b8ff2cc9b4..9cb2e0336a 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -103,8 +103,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry class LLViewerFolderDictionary : public LLSingleton, public LLDictionary { -public: - LLViewerFolderDictionary(); + LLSINGLETON(LLViewerFolderDictionary); protected: bool initEnsemblesFromFile(); // Reads in ensemble information from foldertypes.xml }; diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h index a983012e2e..da50e07a43 100644 --- a/indra/newview/llviewerhelp.h +++ b/indra/newview/llviewerhelp.h @@ -39,7 +39,7 @@ class LLUICtrl; class LLViewerHelp : public LLHelp, public LLSingleton { - friend class LLSingleton; + LLSINGLETON_EMPTY_CTOR(LLViewerHelp); public: /// display the specified help topic in the help viewer diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d0813544f8..557e20a4b0 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -94,107 +94,10 @@ void doInventoryCb(LLPointer cb, LLUUID id) ///---------------------------------------------------------------------------- class LLLocalizedInventoryItemsDictionary : public LLSingleton { + LLSINGLETON(LLLocalizedInventoryItemsDictionary); public: std::map mInventoryItemsDict; - LLLocalizedInventoryItemsDictionary() - { - mInventoryItemsDict["New Shape"] = LLTrans::getString("New Shape"); - mInventoryItemsDict["New Skin"] = LLTrans::getString("New Skin"); - mInventoryItemsDict["New Hair"] = LLTrans::getString("New Hair"); - mInventoryItemsDict["New Eyes"] = LLTrans::getString("New Eyes"); - mInventoryItemsDict["New Shirt"] = LLTrans::getString("New Shirt"); - mInventoryItemsDict["New Pants"] = LLTrans::getString("New Pants"); - mInventoryItemsDict["New Shoes"] = LLTrans::getString("New Shoes"); - mInventoryItemsDict["New Socks"] = LLTrans::getString("New Socks"); - mInventoryItemsDict["New Jacket"] = LLTrans::getString("New Jacket"); - mInventoryItemsDict["New Gloves"] = LLTrans::getString("New Gloves"); - mInventoryItemsDict["New Undershirt"] = LLTrans::getString("New Undershirt"); - mInventoryItemsDict["New Underpants"] = LLTrans::getString("New Underpants"); - mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt"); - mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha"); - mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo"); - mInventoryItemsDict["New Physics"] = LLTrans::getString("New Physics"); - mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); - - mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture"); - mInventoryItemsDict["New Script"] = LLTrans::getString("New Script"); - mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder"); - mInventoryItemsDict["New Note"] = LLTrans::getString("New Note"); - mInventoryItemsDict["Contents"] = LLTrans::getString("Contents"); - - mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture"); - mInventoryItemsDict["Male Gestures"] = LLTrans::getString("Male Gestures"); - mInventoryItemsDict["Female Gestures"] = LLTrans::getString("Female Gestures"); - mInventoryItemsDict["Other Gestures"] = LLTrans::getString("Other Gestures"); - mInventoryItemsDict["Speech Gestures"] = LLTrans::getString("Speech Gestures"); - mInventoryItemsDict["Common Gestures"] = LLTrans::getString("Common Gestures"); - - //predefined gestures - - //male - mInventoryItemsDict["Male - Excuse me"] = LLTrans::getString("Male - Excuse me"); - mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319 - mInventoryItemsDict["Male - Blow kiss"] = LLTrans::getString("Male - Blow kiss"); - mInventoryItemsDict["Male - Boo"] = LLTrans::getString("Male - Boo"); - mInventoryItemsDict["Male - Bored"] = LLTrans::getString("Male - Bored"); - mInventoryItemsDict["Male - Hey"] = LLTrans::getString("Male - Hey"); - mInventoryItemsDict["Male - Laugh"] = LLTrans::getString("Male - Laugh"); - mInventoryItemsDict["Male - Repulsed"] = LLTrans::getString("Male - Repulsed"); - mInventoryItemsDict["Male - Shrug"] = LLTrans::getString("Male - Shrug"); - mInventoryItemsDict["Male - Stick tougue out"] = LLTrans::getString("Male - Stick tougue out"); - mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow"); - - //female - mInventoryItemsDict["Female - Chuckle"] = LLTrans::getString("Female - Chuckle"); - mInventoryItemsDict["Female - Cry"] = LLTrans::getString("Female - Cry"); - mInventoryItemsDict["Female - Embarrassed"] = LLTrans::getString("Female - Embarrassed"); - mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me"); - mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319 - mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss"); - mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo"); - mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored"); - mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey"); - mInventoryItemsDict["Female - Hey baby"] = LLTrans::getString("Female - Hey baby"); - mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh"); - mInventoryItemsDict["Female - Looking good"] = LLTrans::getString("Female - Looking good"); - mInventoryItemsDict["Female - Over here"] = LLTrans::getString("Female - Over here"); - mInventoryItemsDict["Female - Please"] = LLTrans::getString("Female - Please"); - mInventoryItemsDict["Female - Repulsed"] = LLTrans::getString("Female - Repulsed"); - mInventoryItemsDict["Female - Shrug"] = LLTrans::getString("Female - Shrug"); - mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out"); - mInventoryItemsDict["Female - Wow"] = LLTrans::getString("Female - Wow"); - - //common - mInventoryItemsDict["/bow"] = LLTrans::getString("/bow"); - mInventoryItemsDict["/clap"] = LLTrans::getString("/clap"); - mInventoryItemsDict["/count"] = LLTrans::getString("/count"); - mInventoryItemsDict["/extinguish"] = LLTrans::getString("/extinguish"); - mInventoryItemsDict["/kmb"] = LLTrans::getString("/kmb"); - mInventoryItemsDict["/muscle"] = LLTrans::getString("/muscle"); - mInventoryItemsDict["/no"] = LLTrans::getString("/no"); - mInventoryItemsDict["/no!"] = LLTrans::getString("/no!"); - mInventoryItemsDict["/paper"] = LLTrans::getString("/paper"); - mInventoryItemsDict["/pointme"] = LLTrans::getString("/pointme"); - mInventoryItemsDict["/pointyou"] = LLTrans::getString("/pointyou"); - mInventoryItemsDict["/rock"] = LLTrans::getString("/rock"); - mInventoryItemsDict["/scissor"] = LLTrans::getString("/scissor"); - mInventoryItemsDict["/smoke"] = LLTrans::getString("/smoke"); - mInventoryItemsDict["/stretch"] = LLTrans::getString("/stretch"); - mInventoryItemsDict["/whistle"] = LLTrans::getString("/whistle"); - mInventoryItemsDict["/yes"] = LLTrans::getString("/yes"); - mInventoryItemsDict["/yes!"] = LLTrans::getString("/yes!"); - mInventoryItemsDict["afk"] = LLTrans::getString("afk"); - mInventoryItemsDict["dance1"] = LLTrans::getString("dance1"); - mInventoryItemsDict["dance2"] = LLTrans::getString("dance2"); - mInventoryItemsDict["dance3"] = LLTrans::getString("dance3"); - mInventoryItemsDict["dance4"] = LLTrans::getString("dance4"); - mInventoryItemsDict["dance5"] = LLTrans::getString("dance5"); - mInventoryItemsDict["dance6"] = LLTrans::getString("dance6"); - mInventoryItemsDict["dance7"] = LLTrans::getString("dance7"); - mInventoryItemsDict["dance8"] = LLTrans::getString("dance8"); - } - /** * Finds passed name in dictionary and replaces it with found localized value. * @@ -217,6 +120,103 @@ public: } }; +LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary() +{ + mInventoryItemsDict["New Shape"] = LLTrans::getString("New Shape"); + mInventoryItemsDict["New Skin"] = LLTrans::getString("New Skin"); + mInventoryItemsDict["New Hair"] = LLTrans::getString("New Hair"); + mInventoryItemsDict["New Eyes"] = LLTrans::getString("New Eyes"); + mInventoryItemsDict["New Shirt"] = LLTrans::getString("New Shirt"); + mInventoryItemsDict["New Pants"] = LLTrans::getString("New Pants"); + mInventoryItemsDict["New Shoes"] = LLTrans::getString("New Shoes"); + mInventoryItemsDict["New Socks"] = LLTrans::getString("New Socks"); + mInventoryItemsDict["New Jacket"] = LLTrans::getString("New Jacket"); + mInventoryItemsDict["New Gloves"] = LLTrans::getString("New Gloves"); + mInventoryItemsDict["New Undershirt"] = LLTrans::getString("New Undershirt"); + mInventoryItemsDict["New Underpants"] = LLTrans::getString("New Underpants"); + mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt"); + mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha"); + mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo"); + mInventoryItemsDict["New Physics"] = LLTrans::getString("New Physics"); + mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); + + mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture"); + mInventoryItemsDict["New Script"] = LLTrans::getString("New Script"); + mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder"); + mInventoryItemsDict["New Note"] = LLTrans::getString("New Note"); + mInventoryItemsDict["Contents"] = LLTrans::getString("Contents"); + + mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture"); + mInventoryItemsDict["Male Gestures"] = LLTrans::getString("Male Gestures"); + mInventoryItemsDict["Female Gestures"] = LLTrans::getString("Female Gestures"); + mInventoryItemsDict["Other Gestures"] = LLTrans::getString("Other Gestures"); + mInventoryItemsDict["Speech Gestures"] = LLTrans::getString("Speech Gestures"); + mInventoryItemsDict["Common Gestures"] = LLTrans::getString("Common Gestures"); + + //predefined gestures + + //male + mInventoryItemsDict["Male - Excuse me"] = LLTrans::getString("Male - Excuse me"); + mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319 + mInventoryItemsDict["Male - Blow kiss"] = LLTrans::getString("Male - Blow kiss"); + mInventoryItemsDict["Male - Boo"] = LLTrans::getString("Male - Boo"); + mInventoryItemsDict["Male - Bored"] = LLTrans::getString("Male - Bored"); + mInventoryItemsDict["Male - Hey"] = LLTrans::getString("Male - Hey"); + mInventoryItemsDict["Male - Laugh"] = LLTrans::getString("Male - Laugh"); + mInventoryItemsDict["Male - Repulsed"] = LLTrans::getString("Male - Repulsed"); + mInventoryItemsDict["Male - Shrug"] = LLTrans::getString("Male - Shrug"); + mInventoryItemsDict["Male - Stick tougue out"] = LLTrans::getString("Male - Stick tougue out"); + mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow"); + + //female + mInventoryItemsDict["Female - Chuckle"] = LLTrans::getString("Female - Chuckle"); + mInventoryItemsDict["Female - Cry"] = LLTrans::getString("Female - Cry"); + mInventoryItemsDict["Female - Embarrassed"] = LLTrans::getString("Female - Embarrassed"); + mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me"); + mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319 + mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss"); + mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo"); + mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored"); + mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey"); + mInventoryItemsDict["Female - Hey baby"] = LLTrans::getString("Female - Hey baby"); + mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh"); + mInventoryItemsDict["Female - Looking good"] = LLTrans::getString("Female - Looking good"); + mInventoryItemsDict["Female - Over here"] = LLTrans::getString("Female - Over here"); + mInventoryItemsDict["Female - Please"] = LLTrans::getString("Female - Please"); + mInventoryItemsDict["Female - Repulsed"] = LLTrans::getString("Female - Repulsed"); + mInventoryItemsDict["Female - Shrug"] = LLTrans::getString("Female - Shrug"); + mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out"); + mInventoryItemsDict["Female - Wow"] = LLTrans::getString("Female - Wow"); + + //common + mInventoryItemsDict["/bow"] = LLTrans::getString("/bow"); + mInventoryItemsDict["/clap"] = LLTrans::getString("/clap"); + mInventoryItemsDict["/count"] = LLTrans::getString("/count"); + mInventoryItemsDict["/extinguish"] = LLTrans::getString("/extinguish"); + mInventoryItemsDict["/kmb"] = LLTrans::getString("/kmb"); + mInventoryItemsDict["/muscle"] = LLTrans::getString("/muscle"); + mInventoryItemsDict["/no"] = LLTrans::getString("/no"); + mInventoryItemsDict["/no!"] = LLTrans::getString("/no!"); + mInventoryItemsDict["/paper"] = LLTrans::getString("/paper"); + mInventoryItemsDict["/pointme"] = LLTrans::getString("/pointme"); + mInventoryItemsDict["/pointyou"] = LLTrans::getString("/pointyou"); + mInventoryItemsDict["/rock"] = LLTrans::getString("/rock"); + mInventoryItemsDict["/scissor"] = LLTrans::getString("/scissor"); + mInventoryItemsDict["/smoke"] = LLTrans::getString("/smoke"); + mInventoryItemsDict["/stretch"] = LLTrans::getString("/stretch"); + mInventoryItemsDict["/whistle"] = LLTrans::getString("/whistle"); + mInventoryItemsDict["/yes"] = LLTrans::getString("/yes"); + mInventoryItemsDict["/yes!"] = LLTrans::getString("/yes!"); + mInventoryItemsDict["afk"] = LLTrans::getString("afk"); + mInventoryItemsDict["dance1"] = LLTrans::getString("dance1"); + mInventoryItemsDict["dance2"] = LLTrans::getString("dance2"); + mInventoryItemsDict["dance3"] = LLTrans::getString("dance3"); + mInventoryItemsDict["dance4"] = LLTrans::getString("dance4"); + mInventoryItemsDict["dance5"] = LLTrans::getString("dance5"); + mInventoryItemsDict["dance6"] = LLTrans::getString("dance6"); + mInventoryItemsDict["dance7"] = LLTrans::getString("dance7"); + mInventoryItemsDict["dance8"] = LLTrans::getString("dance8"); +} ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index 80c758a5af..016b435ee8 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -45,10 +45,10 @@ typedef enum e_joystick_driver_state class LLViewerJoystick : public LLSingleton { -public: - LLViewerJoystick(); + LLSINGLETON(LLViewerJoystick); virtual ~LLViewerJoystick(); - + +public: void init(bool autoenable); void terminate(); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 2186ed3c52..fd4315a319 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -57,6 +57,7 @@ const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed struct LLKeyboardActionRegistry : public LLRegistrySingleton, LLKeyboardActionRegistry> { + LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); }; LLViewerKeyboard gViewerKeyboard; diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index 0b2a64868e..368c671f84 100644 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -41,10 +41,10 @@ class LLViewerMediaFocus : public LLFocusableElement, public LLSingleton { -public: - LLViewerMediaFocus(); + LLSINGLETON(LLViewerMediaFocus); ~LLViewerMediaFocus(); - + +public: // Set/clear the face that has media focus (takes keyboard input and has the full set of controls) void setFocusFace(LLPointer objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero); void clearFocus(); diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index d8f5c71f8d..b0eaa37541 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -210,6 +210,7 @@ void set_dad_inbox_object(const LLUUID& object_id); class LLViewerMessage : public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLViewerMessage); public: typedef boost::function teleport_started_callback_t; typedef boost::signals2::signal teleport_started_signal_t; diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 6666aecca2..b47cdbd111 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -91,13 +91,6 @@ LLGridManager::LLGridManager() } -LLGridManager::LLGridManager(const std::string& grid_file) -{ - // initialize with an explicity grid file for testing. - LL_DEBUGS("GridManager")< { + /// Instantiate the grid manager, load default grids, selects the default grid + LLSINGLETON(LLGridManager); + ~LLGridManager(); + public: /* ================================================================ * @name Initialization and Configuration * @{ */ - /// Instantiate the grid manager, load default grids, selects the default grid - LLGridManager(const std::string& grid_file); - LLGridManager(); - ~LLGridManager(); - /// add grids from an external grids file void initialize(const std::string& grid_file); diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index bb6bbf3308..29219843c9 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -75,6 +75,8 @@ public: class LLViewerParcelMgr : public LLSingleton { + LLSINGLETON(LLViewerParcelMgr); + ~LLViewerParcelMgr(); public: typedef boost::function teleport_finished_callback_t; @@ -82,9 +84,6 @@ public: typedef boost::function teleport_failed_callback_t; typedef boost::signals2::signal teleport_failed_signal_t; - LLViewerParcelMgr(); - ~LLViewerParcelMgr(); - static void cleanupGlobals(); BOOL selectionEmpty() const; diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 40e8e1d45d..ab1cd715ab 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -135,9 +135,8 @@ protected: class LLViewerPartSim : public LLSingleton { + LLSINGLETON(LLViewerPartSim); public: - LLViewerPartSim(); - virtual ~LLViewerPartSim(){} void destroyClass(); typedef std::vector group_list_t; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 7843652589..97a060d95e 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -246,13 +246,11 @@ extern LLTrace::EventStatHandle > OBJECT_CACHE_HIT class LLViewerStats : public LLSingleton { -public: - void resetStats(); + LLSINGLETON(LLViewerStats); + ~LLViewerStats(); public: - - LLViewerStats(); - ~LLViewerStats(); + void resetStats(); void updateFrameStats(const F64Seconds time_diff); diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h index d1744f4910..c974bea49d 100644 --- a/indra/newview/llviewerstatsrecorder.h +++ b/indra/newview/llviewerstatsrecorder.h @@ -44,11 +44,11 @@ class LLViewerObject; class LLViewerStatsRecorder : public LLSingleton { - public: - LOG_CLASS(LLViewerStatsRecorder); - LLViewerStatsRecorder(); + LLSINGLETON(LLViewerStatsRecorder); + LOG_CLASS(LLViewerStatsRecorder); ~LLViewerStatsRecorder(); + public: void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) { #if LL_RECORD_VIEWER_STATS diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index ba76770838..070544063a 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -237,6 +237,7 @@ private: class LLUIImageList : public LLImageProviderInterface, public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLUIImageList); public: // LLImageProviderInterface /*virtual*/ LLPointer getUIImageByID(const LLUUID& id, S32 priority); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e3e7b81f2f..45cb014e43 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -288,13 +288,8 @@ public: class RecordToChatConsole : public LLSingleton { + LLSINGLETON(RecordToChatConsole); public: - RecordToChatConsole() - : LLSingleton(), - mRecorder(new RecordToChatConsoleRecorder()) - { - } - void startRecorder() { LLError::addRecorder(mRecorder); } void stopRecorder() { LLError::removeRecorder(mRecorder); } @@ -302,6 +297,11 @@ private: LLError::RecorderPtr mRecorder; }; +RecordToChatConsole::RecordToChatConsole(): + mRecorder(new RecordToChatConsoleRecorder()) +{ +} + //////////////////////////////////////////////////////////////////////////// // // LLDebugText @@ -2120,10 +2120,7 @@ void LLViewerWindow::shutdownViews() // destroy the nav bar, not currently part of gViewerWindow // *TODO: Make LLNavigationBar part of gViewerWindow - if (LLNavigationBar::instanceExists()) - { - delete LLNavigationBar::getInstance(); - } + LLNavigationBar::deleteSingleton(); LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ; // destroy menus after instantiating navbar above, as it needs diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 082f5f0b1d..7aabde1b2d 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -223,6 +223,9 @@ private: // class LLVOCache : public LLSingleton { + LLSINGLETON(LLVOCache); + ~LLVOCache() ; + private: struct HeaderEntryInfo { @@ -253,13 +256,8 @@ private: }; typedef std::set header_entry_queue_t; typedef std::map handle_entry_map_t; -private: - friend class LLSingleton; - LLVOCache() ; public: - ~LLVOCache() ; - void initCache(ELLPath location, U32 size, U32 cache_version) ; void removeCache(ELLPath location, bool started = false) ; diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index ef15b2c79e..309c3eebdd 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -167,8 +167,8 @@ private: class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton { + LLSINGLETON(LLVoiceChannelProximal); public: - LLVoiceChannelProximal(); /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); /*virtual*/ void handleStatusChange(EStatusType status); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index b05bcb23b7..32637dcf42 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -299,11 +299,11 @@ public: class LLVoiceClient: public LLSingleton { + LLSINGLETON(LLVoiceClient); LOG_CLASS(LLVoiceClient); -public: - LLVoiceClient(); ~LLVoiceClient(); +public: typedef boost::signals2::signal micro_changed_signal_t; micro_changed_signal_t mMicroChangedSignal; @@ -485,6 +485,8 @@ protected: **/ class LLSpeakerVolumeStorage : public LLSingleton { + LLSINGLETON(LLSpeakerVolumeStorage); + ~LLSpeakerVolumeStorage(); LOG_CLASS(LLSpeakerVolumeStorage); public: @@ -513,10 +515,6 @@ public: void removeSpeakerVolume(const LLUUID& speaker_id); private: - friend class LLSingleton; - LLSpeakerVolumeStorage(); - ~LLSpeakerVolumeStorage(); - const static std::string SETTINGS_FILE_NAME; void load(); diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index f32c7c975f..81e924e438 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -56,12 +56,11 @@ class LLVivoxVoiceClient : public LLSingleton, virtual public LLVoiceModuleInterface, virtual public LLVoiceEffectInterface { + LLSINGLETON(LLVivoxVoiceClient); LOG_CLASS(LLVivoxVoiceClient); -public: - LLVivoxVoiceClient(); virtual ~LLVivoxVoiceClient(); - - + +public: /// @name LLVoiceModuleInterface virtual implementations /// @see LLVoiceModuleInterface //@{ @@ -1027,10 +1026,10 @@ protected: class LLVivoxSecurity : public LLSingleton { - public: - LLVivoxSecurity(); - virtual ~LLVivoxSecurity(); + LLSINGLETON(LLVivoxSecurity); + virtual ~LLVivoxSecurity(); + public: std::string connectorHandle() { return mConnectorHandle; }; std::string accountHandle() { return mAccountHandle; }; diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h index fee3ec6f20..9a6624258e 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -75,10 +75,10 @@ private: class LLWatchdogTimerThread; // Defined in the cpp class LLWatchdog : public LLSingleton { -public: - LLWatchdog(); + LLSINGLETON(LLWatchdog); ~LLWatchdog(); +public: // Add an entry to the watchdog. void add(LLWatchdogEntry* e); void remove(LLWatchdogEntry* e); diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h index dc7d41be2a..3f169e439a 100644 --- a/indra/newview/llwaterparammanager.h +++ b/indra/newview/llwaterparammanager.h @@ -214,6 +214,8 @@ struct WaterExpFloatControl /// WindLight parameter manager class - what controls all the wind light shaders class LLWaterParamManager : public LLSingleton { + LLSINGLETON(LLWaterParamManager); + ~LLWaterParamManager(); LOG_CLASS(LLWaterParamManager); public: typedef std::list preset_name_list_t; @@ -317,11 +319,7 @@ public: F32 mDensitySliderValue; private: - friend class LLSingleton; /*virtual*/ void initSingleton(); - LLWaterParamManager(); - ~LLWaterParamManager(); - void loadAllPresets(); void loadPresetsFromDir(const std::string& dir); bool loadPreset(const std::string& path); diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 18a30f083b..6aa03e16ed 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -411,8 +411,8 @@ public: */ class ContextMenu : public LLListContextMenu, public LLSingleton { + LLSINGLETON(ContextMenu); public: - ContextMenu(); /*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y); protected: diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h index d6f0fd09a6..782f7751e5 100644 --- a/indra/newview/llwearablelist.h +++ b/indra/newview/llwearablelist.h @@ -41,9 +41,9 @@ */ class LLWearableList : public LLSingleton { -public: - LLWearableList() {} + LLSINGLETON_EMPTY_CTOR(LLWearableList); ~LLWearableList(); +public: void cleanup() ; S32 getLength() const { return mList.size(); } diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h index a3cbf6dc03..89297e94e1 100644 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -34,6 +34,7 @@ class LLWinDebug: public LLSingleton { + LLSINGLETON(LLWinDebug); public: static void init(); static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index e13aed98ed..a10102edf7 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -213,6 +213,8 @@ public: /// WindLight parameter manager class - what controls all the wind light shaders class LLWLParamManager : public LLSingleton { + LLSINGLETON(LLWLParamManager); + ~LLWLParamManager(); LOG_CLASS(LLWLParamManager); public: @@ -375,11 +377,7 @@ private: static std::string getSysDir(); static std::string getUserDir(); - friend class LLSingleton; /*virtual*/ void initSingleton(); - LLWLParamManager(); - ~LLWLParamManager(); - // list of all the parameters, listed by name std::map mParamList; diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b2d8418064..c9ac241d5a 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -61,8 +61,8 @@ class LLVOAvatar; class LLWorld : public LLSingleton { + LLSINGLETON(LLWorld); public: - LLWorld(); void destroyClass(); LLViewerRegion* addRegion(const U64 ®ion_handle, const LLHost &host); diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 1a168e4b4d..5e5caa6a74 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -193,10 +193,10 @@ const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE); class LLWorldMap : public LLSingleton { -public: - LLWorldMap(); + LLSINGLETON(LLWorldMap); ~LLWorldMap(); +public: // Clear all: list of region info, tiles, blocks and items void reset(); diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h index ac1ea1607c..65276df068 100644 --- a/indra/newview/llworldmapmessage.h +++ b/indra/newview/llworldmapmessage.h @@ -34,13 +34,13 @@ class LLMessageSystem; class LLWorldMapMessage : public LLSingleton { + LLSINGLETON(LLWorldMapMessage); + ~LLWorldMapMessage(); + public: typedef boost::function url_callback_t; - LLWorldMapMessage(); - ~LLWorldMapMessage(); - // Process incoming answers to map stuff requests static void processMapBlockReply(LLMessageSystem*, void**); static void processMapItemReply(LLMessageSystem*, void**); -- cgit v1.3 From 0dcb423cf3dc42e11621eece972801b036657e91 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 25 Apr 2017 17:48:34 +0300 Subject: MAINT-7145 Eliminate LLSingleton circular references --- indra/llcommon/llsingleton.cpp | 32 +++++++++++++++++++++++++++----- indra/llui/llnotifications.cpp | 18 ++++++------------ indra/newview/lldaycyclemanager.cpp | 22 ---------------------- indra/newview/llenvmanager.cpp | 21 ++++++++++++++++++++- indra/newview/llsky.cpp | 2 -- indra/newview/llstartup.cpp | 1 + indra/newview/llwlparammanager.cpp | 25 ++++++++----------------- indra/newview/llwlparammanager.h | 5 +++-- 8 files changed, 65 insertions(+), 61 deletions(-) (limited to 'indra/llcommon/llsingleton.cpp') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 9025e53bb2..a3a87edd88 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -220,6 +220,9 @@ void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initSt std::find(initializing.begin(), initializing.end(), this); if (found != initializing.end()) { + list_t::const_iterator it_next = found; + it_next++; + // Report the circularity. Requiring the coder to dig through the // logic to diagnose exactly how we got here is less than helpful. std::ostringstream out; @@ -238,11 +241,30 @@ void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initSt // otherwise we'd be returning a pointer to a partially- // constructed object! But from initSingleton() is okay: that // method exists specifically to support circularity. - // Decide which log helper to call based on initState. They have - // identical signatures. - ((initState == CONSTRUCTING)? logerrs : logwarns) - ("LLSingleton circularity: ", out.str().c_str(), - demangle(typeid(*this).name()).c_str(), ""); + // Decide which log helper to call. + if (initState == CONSTRUCTING) + { + logerrs("LLSingleton circularity in Constructor: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } + else if (it_next == initializing.end()) + { + // Points to self after construction, but during initialization. + // Singletons can initialize other classes that depend onto them, + // so this is expected. + // + // Example: LLNotifications singleton initializes default channels. + // Channels register themselves with singleton once done. + logdebugs("LLSingleton circularity: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } + else + { + // Actual circularity with other singleton (or single singleton is used extensively). + // Dependency can be unclear. + logwarns("LLSingleton circularity: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } } else { diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 0cb959a315..604092d536 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1405,20 +1405,14 @@ void LLNotifications::createDefaultChannels() mDefaultChannels.push_back(new LLPersistentNotificationChannel()); // connect action methods to these channels - LLNotifications::instance().getChannel("Enabled")-> - connectFailedFilter(&defaultResponse); - LLNotifications::instance().getChannel("Expiration")-> - connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1)); + getChannel("Enabled")->connectFailedFilter(&defaultResponse); + getChannel("Expiration")->connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1)); // uniqueHandler slot should be added as first slot of the signal due to // usage LLStopWhenHandled combiner in LLStandardSignal - LLNotifications::instance().getChannel("Unique")-> - connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1)); - LLNotifications::instance().getChannel("Unique")-> - connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1)); - LLNotifications::instance().getChannel("Ignore")-> - connectFailedFilter(&handleIgnoredNotification); - LLNotifications::instance().getChannel("VisibilityRules")-> - connectFailedFilter(&visibilityRuleMached); + getChannel("Unique")->connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1)); + getChannel("Unique")->connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1)); + getChannel("Ignore")->connectFailedFilter(&handleIgnoredNotification); + getChannel("VisibilityRules")->connectFailedFilter(&visibilityRuleMached); } diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp index e7bf989850..803e2b2fb2 100644 --- a/indra/newview/lldaycyclemanager.cpp +++ b/indra/newview/lldaycyclemanager.cpp @@ -163,28 +163,6 @@ void LLDayCycleManager::initSingleton() { LL_DEBUGS("Windlight") << "Loading all day cycles" << LL_ENDL; loadAllPresets(); - - // presets loaded, can set params - if (LLEnvManagerNew::instance().getUseDayCycle()) - { - LLSD params; - std::string preferred_day = LLEnvManagerNew::getInstance()->getDayCycleName(); - if (getPreset(preferred_day, params)) - { - // Same as through useDayCycle(), but it will call LLDayCycleManager and we are initializing - // so no need to cycle - LLWLParamManager::getInstance()->applyDayCycleParams(params, LLEnvKey::SCOPE_LOCAL); - } - else - { - LL_WARNS() << "No day cycle named " << preferred_day << ", reverting LLWLParamManager to defaults" << LL_ENDL; - LLWLParamManager::getInstance()->setDefaultDay(); - } - } - else - { - LLWLParamManager::getInstance()->setDefaultDay(); - } } void LLDayCycleManager::loadAllPresets() diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index b97e483fd9..12c3070474 100644 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -476,7 +476,7 @@ void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content) mCachedRegionPrefs = new_settings; // Load region sky presets. - LLWLParamManager::instance().refreshRegionPresets(); + LLWLParamManager::instance().refreshRegionPresets(getRegionSettings().getSkyMap()); // If using server settings, update managers. if (getUseRegionSettings()) @@ -509,6 +509,25 @@ void LLEnvManagerNew::initSingleton() LL_DEBUGS("Windlight") << "Initializing LLEnvManagerNew" << LL_ENDL; loadUserPrefs(); + + // preferences loaded, can set params + std::string preferred_day = getDayCycleName(); + if (!useDayCycle(preferred_day, LLEnvKey::SCOPE_LOCAL)) + { + LL_WARNS() << "No day cycle named " << preferred_day << ", reverting LLWLParamManager to defaults" << LL_ENDL; + LLWLParamManager::instance().setDefaultDay(); + } + + std::string sky = getSkyPresetName(); + if (!useSkyPreset(sky)) + { + LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL; + LLWLParamManager::instance().setDefaultSky(); + + // *TODO: Fix user preferences accordingly. + } + + LLWLParamManager::instance().resetAnimator(0.5 /*noon*/, getUseDayCycle()); } void LLEnvManagerNew::updateSkyFromPrefs() diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index 7a292fe0ef..3ef89ba920 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -341,8 +341,6 @@ void LLSky::init(const LLVector3 &sun_direction) LLGLState::checkTextureChannels(); mUpdatedThisFrame = TRUE; - - LLEnvManagerNew::instance().usePrefs(); //inits day cycles and water } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0a85344025..33b6352bf5 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1462,6 +1462,7 @@ bool idle_startup() LLGLState::checkStates(); LLGLState::checkTextureChannels(); + LLEnvManagerNew::getInstance()->usePrefs(); // Load all presets and settings gSky.init(initial_sun_direction); LLGLState::checkStates(); diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index debe467a9a..4b4393b07b 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -50,7 +50,6 @@ #include "llagent.h" #include "llviewerregion.h" -#include "llenvmanager.h" #include "llwlparamset.h" #include "llpostprocess.h" @@ -251,13 +250,13 @@ void LLWLParamManager::addAllSkies(const LLWLParamKey::EScope scope, const LLSD& } } -void LLWLParamManager::refreshRegionPresets() +void LLWLParamManager::refreshRegionPresets(const LLSD& region_sky_presets) { // Remove all region sky presets because they may belong to a previously visited region. clearParamSetsOfScope(LLEnvKey::SCOPE_REGION); // Add all sky presets belonging to the current region. - addAllSkies(LLEnvKey::SCOPE_REGION, LLEnvManagerNew::instance().getRegionSettings().getSkyMap()); + addAllSkies(LLEnvKey::SCOPE_REGION, region_sky_presets); } void LLWLParamManager::loadAllPresets() @@ -489,7 +488,6 @@ bool LLWLParamManager::applyDayCycleParams(const LLSD& params, LLEnvKey::EScope void LLWLParamManager::setDefaultDay() { mDay.loadDayCycleFromFile("Default.xml"); - resetAnimator(0.5, LLEnvManagerNew::getInstance()->getUseDayCycle()); } bool LLWLParamManager::applySkyParams(const LLSD& params) @@ -499,6 +497,12 @@ bool LLWLParamManager::applySkyParams(const LLSD& params) return true; } +void LLWLParamManager::setDefaultSky() +{ + getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams); +} + + void LLWLParamManager::resetAnimator(F32 curTime, bool run) { mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate, @@ -677,19 +681,6 @@ void LLWLParamManager::initSingleton() loadAllPresets(); - // *HACK - sets cloud scrolling to what we want... fix this better in the future - std::string sky = LLEnvManagerNew::instance().getSkyPresetName(); - if (!getParamSet(LLWLParamKey(sky, LLWLParamKey::SCOPE_LOCAL), mCurParams)) - { - LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL; - getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams); - - // *TODO: Fix user preferences accordingly. - } - - // set it to noon - resetAnimator(0.5, LLEnvManagerNew::instance().getUseDayCycle()); - // but use linden time sets it to what the estate is mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN); } diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index db3c285e76..a8029839a7 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -29,7 +29,6 @@ #include #include -#include "llenvmanager.h" #include "llwlparamset.h" #include "llwlanimator.h" #include "llwldaycycle.h" @@ -246,6 +245,8 @@ public: /// apply specified fixed sky params bool applySkyParams(const LLSD& params); + void setDefaultSky(); + // get where the light is pointing inline LLVector4 getLightDir(void) const; @@ -305,7 +306,7 @@ public: void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map); /// refresh region-scope presets - void refreshRegionPresets(); + void refreshRegionPresets(const LLSD& region_sky_presets); // returns all skies referenced by the current day cycle (in mDay), with their final names // side effect: applies changes to all internal structures! (trashes all unreferenced skies in scope, keys in day cycle rescoped to scope, etc.) -- cgit v1.3