diff --git a/doc/contributions.txt b/doc/contributions.txt index 60f2c11b96..6b2e10ca82 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -206,6 +206,12 @@ Ansariel Hiller MAINT-6636 MAINT-6744 MAINT-6752 + MAINT-6773 + MAINT-6906 + MAINT-6911 + MAINT-6917 + STORM-2140 + MAINT-6912 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 3d27b4a5b5..f4dba16a94 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -42,6 +42,7 @@ #include "lldiriterator.h" #include "v4coloru.h" #include "llsdserialize.h" +#include "llcleanup.h" // system libraries #include @@ -634,7 +635,7 @@ int main(int argc, char** argv) } // Cleanup and exit - LLImage::cleanupClass(); + SUBSYSTEM_CLEANUP(LLImage); if (fast_timer_log_thread) { fast_timer_log_thread->shutdown(); 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 8df4ff4de6..c84644ce84 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); // [RLVa:KB] - Checked: 2010-03-03 (RLVa-1.2.0a) | Added: RLVa-1.2.0a protected: diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 155ffb353d..a5f2034e41 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -40,8 +40,10 @@ set(llcommon_SOURCE_FILES llbitpack.cpp llcallbacklist.cpp llcallstack.cpp + llcleanup.cpp llcommon.cpp llcommonutils.cpp + llcoro_get_id.cpp llcoros.cpp llcrc.cpp llcriticaldamp.cpp @@ -66,7 +68,9 @@ set(llcommon_SOURCE_FILES llformat.cpp llframetimer.cpp llheartbeat.cpp + llheteromap.cpp llinitparam.cpp + llinitdestroyclass.cpp llinstancetracker.cpp llleap.cpp llleaplistener.cpp @@ -137,8 +141,10 @@ set(llcommon_HEADER_FILES llboost.h llcallbacklist.h llcallstack.h + llcleanup.h llcommon.h llcommonutils.h + llcoro_get_id.h llcoros.h llcrc.h llcriticaldamp.h @@ -170,7 +176,9 @@ set(llcommon_HEADER_FILES llhandle.h llhash.h llheartbeat.h + llheteromap.h llindexedvector.h + llinitdestroyclass.h llinitparam.h llinstancetracker.h llkeythrottle.h @@ -187,6 +195,7 @@ set(llcommon_HEADER_FILES llmortician.h llnametable.h llpointer.h + llpounceable.h llpredicate.h llpreprocessor.h llpriqueuemap.h @@ -374,6 +383,8 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}") ## llexception_test.cpp isn't a regression test, and doesn't need to be run ## every build. It's to help a developer make implementation choices about diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index d9af7ad0c4..a8bedffd5b 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -50,6 +50,7 @@ #include "google_breakpad/exception_handler.h" #include "stringize.h" +#include "llcleanup.h" // // Signal handling @@ -181,7 +182,7 @@ LLApp::~LLApp() if(mExceptionHandler != 0) delete mExceptionHandler; - LLCommon::cleanupClass(); + SUBSYSTEM_CLEANUP(LLCommon); } // static 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/llcleanup.cpp b/indra/llcommon/llcleanup.cpp new file mode 100644 index 0000000000..c5283507bf --- /dev/null +++ b/indra/llcommon/llcleanup.cpp @@ -0,0 +1,29 @@ +/** + * @file llcleanup.cpp + * @author Nat Goodspeed + * @date 2016-08-30 + * @brief Implementation for llcleanup. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llcleanup.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" +#include "llerrorcontrol.h" + +void log_subsystem_cleanup(const char* file, int line, const char* function, + const char* classname) +{ + LL_INFOS("Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): " + << "calling " << classname << "::cleanupClass() in " + << function << LL_ENDL; +} diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h new file mode 100644 index 0000000000..a319171b5f --- /dev/null +++ b/indra/llcommon/llcleanup.h @@ -0,0 +1,33 @@ +/** + * @file llcleanup.h + * @author Nat Goodspeed + * @date 2015-05-20 + * @brief Mechanism for cleaning up subsystem resources + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLCLEANUP_H) +#define LL_LLCLEANUP_H + +#include + +// Instead of directly calling SomeClass::cleanupClass(), use +// SUBSYSTEM_CLEANUP(SomeClass); +// This logs the call as well as performing it. That gives us a baseline +// subsystem shutdown order against which to compare subsequent dynamic +// shutdown schemes. +#define SUBSYSTEM_CLEANUP(CLASSNAME) \ + do { \ + log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \ + CLASSNAME::cleanupClass(); \ + } while (0) +// Use ancient do { ... } while (0) macro trick to permit a block of +// statements with the same syntax as a single statement. + +void log_subsystem_cleanup(const char* file, int line, const char* function, + const char* classname); + +#endif /* ! defined(LL_LLCLEANUP_H) */ diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 19642b0982..439ff4e628 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -31,6 +31,7 @@ #include "llthread.h" #include "lltrace.h" #include "lltracethreadrecorder.h" +#include "llcleanup.h" //static BOOL LLCommon::sAprInitialized = FALSE; @@ -63,11 +64,11 @@ void LLCommon::cleanupClass() sMasterThreadRecorder = NULL; LLTrace::set_master_thread_recorder(NULL); LLThreadSafeRefCount::cleanupThreadSafeRefCount(); - LLTimer::cleanupClass(); + SUBSYSTEM_CLEANUP(LLTimer); if (sAprInitialized) { ll_cleanup_apr(); sAprInitialized = FALSE; } - LLMemory::cleanupClass(); + SUBSYSTEM_CLEANUP(LLMemory); } diff --git a/indra/llcommon/llcoro_get_id.cpp b/indra/llcommon/llcoro_get_id.cpp new file mode 100644 index 0000000000..24ed1fe0c9 --- /dev/null +++ b/indra/llcommon/llcoro_get_id.cpp @@ -0,0 +1,32 @@ +/** + * @file llcoro_get_id.cpp + * @author Nat Goodspeed + * @date 2016-09-03 + * @brief Implementation for llcoro_get_id. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llcoro_get_id.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llcoros.h" + +namespace llcoro +{ + +id get_id() +{ + // An instance of Current can convert to LLCoros::CoroData*, which can + // implicitly convert to void*, which is an llcoro::id. + return LLCoros::Current(); +} + +} // llcoro diff --git a/indra/llcommon/llcoro_get_id.h b/indra/llcommon/llcoro_get_id.h new file mode 100644 index 0000000000..4c1dca6f19 --- /dev/null +++ b/indra/llcommon/llcoro_get_id.h @@ -0,0 +1,30 @@ +/** + * @file llcoro_get_id.h + * @author Nat Goodspeed + * @date 2016-09-03 + * @brief Supplement the functionality in llcoro.h. + * + * This is broken out as a separate header file to resolve + * circularity: LLCoros isa LLSingleton, yet LLSingleton machinery + * requires llcoro::get_id(). + * + * Be very suspicious of anyone else #including this header. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLCORO_GET_ID_H) +#define LL_LLCORO_GET_ID_H + +namespace llcoro +{ + +/// Get an opaque, distinct token for the running coroutine (or main). +typedef void* id; +id get_id(); + +} // llcoro + +#endif /* ! defined(LL_LLCORO_GET_ID_H) */ diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index bc72faca5d..1e1dfd2602 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -40,32 +40,79 @@ #include "stringize.h" #include "llexception.h" -// do nothing, when we need nothing done +namespace { +void no_op() {} +} // anonymous namespace + +// Do nothing, when we need nothing done. This is a static member of LLCoros +// because CoroData is a private nested class. void LLCoros::no_cleanup(CoroData*) {} // CoroData for the currently-running coroutine. Use a thread_specific_ptr // because each thread potentially has its own distinct pool of coroutines. -// This thread_specific_ptr does NOT own the CoroData object! That's owned by -// LLCoros::mCoros. It merely identifies it. For this reason we instantiate -// it with a no-op cleanup function. -boost::thread_specific_ptr -LLCoros::sCurrentCoro(LLCoros::no_cleanup); +LLCoros::Current::Current() +{ + // Use a function-static instance so this thread_specific_ptr is + // instantiated on demand. Since we happen to know it's consumed by + // LLSingleton, this is likely to happen before the runtime has finished + // initializing module-static data. For the same reason, we can't package + // this pointer in an LLSingleton. + + // This thread_specific_ptr does NOT own the CoroData object! That's owned + // by LLCoros::mCoros. It merely identifies it. For this reason we + // instantiate it with a no-op cleanup function. + static boost::thread_specific_ptr sCurrent(LLCoros::no_cleanup); + + // If this is the first time we're accessing sCurrent for the running + // thread, its get() will be NULL. This could be a problem, in that + // llcoro::get_id() would return the same (NULL) token value for the "main + // coroutine" in every thread, whereas what we really want is a distinct + // value for every distinct stack in the process. So if get() is NULL, + // give it a heap CoroData: this ensures that llcoro::get_id() will return + // distinct values. + // This tactic is "leaky": sCurrent explicitly does not destroy any + // CoroData to which it points, and we do NOT enter these "main coroutine" + // CoroData instances in the LLCoros::mCoros map. They are dummy entries, + // and they will leak at process shutdown: one CoroData per thread. + if (! sCurrent.get()) + { + // It's tempting to provide a distinct name for each thread's "main + // coroutine." But as getName() has always returned the empty string + // to mean "not in a coroutine," empty string should suffice here -- + // and truthfully the additional (thread-safe!) machinery to ensure + // uniqueness just doesn't feel worth the trouble. + // We use a no-op callable and a minimal stack size because, although + // CoroData's constructor in fact initializes its mCoro with a + // coroutine with that stack size, no one ever actually enters it by + // calling mCoro(). + sCurrent.reset(new CoroData(0, // no prev + "", // not a named coroutine + no_op, // no-op callable + 1024)); // stacksize moot + } + + mCurrent = &sCurrent; +} //static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { - CoroData* current = sCurrentCoro.get(); - if (! current) - { - LL_ERRS("LLCoros") << "Calling " << caller << " from non-coroutine context!" << LL_ENDL; - } + CoroData* current = Current(); + // With the dummy CoroData set in LLCoros::Current::Current(), this + // pointer should never be NULL. + llassert_always(current); return *current; } //static LLCoros::coro::self& LLCoros::get_self() { - return *get_CoroData("get_self()").mSelf; + CoroData& current = get_CoroData("get_self()"); + if (! current.mSelf) + { + LL_ERRS("LLCoros") << "Calling get_self() from non-coroutine context!" << LL_ENDL; + } + return *current.mSelf; } //static @@ -80,20 +127,23 @@ bool LLCoros::get_consuming() return get_CoroData("get_consuming()").mConsuming; } -llcoro::Suspending::Suspending(): - mSuspended(LLCoros::sCurrentCoro.get()) +llcoro::Suspending::Suspending() { - // Revert mCurrentCoro to the value it had at the moment we last switched + LLCoros::Current current; + // Remember currently-running coroutine: we're about to suspend it. + mSuspended = current; + // Revert Current to the value it had at the moment we last switched // into this coroutine. - LLCoros::sCurrentCoro.reset(mSuspended->mPrev); + current.reset(mSuspended->mPrev); } llcoro::Suspending::~Suspending() { + LLCoros::Current current; // Okay, we're back, update our mPrev - mSuspended->mPrev = LLCoros::sCurrentCoro.get(); - // and reinstate our sCurrentCoro. - LLCoros::sCurrentCoro.reset(mSuspended); + mSuspended->mPrev = current; + // and reinstate our Current. + current.reset(mSuspended); } LLCoros::LLCoros(): @@ -217,13 +267,7 @@ bool LLCoros::kill(const std::string& name) std::string LLCoros::getName() const { - CoroData* current = sCurrentCoro.get(); - if (! current) - { - // not in a coroutine - return ""; - } - return current->mName; + return Current()->mName; } void LLCoros::setStackSize(S32 stacksize) @@ -233,8 +277,8 @@ void LLCoros::setStackSize(S32 stacksize) } // Top-level wrapper around caller's coroutine callable. This function accepts -// the coroutine library's implicit coro::self& parameter and sets sCurrentSelf -// but does not pass it down to the caller's callable. +// the coroutine library's implicit coro::self& parameter and saves it, but +// does not pass it down to the caller's callable. void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& callable) { // capture the 'self' param in CoroData @@ -258,8 +302,8 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); } // This cleanup isn't perfectly symmetrical with the way we initially set - // data->mPrev, but this is our last chance to reset mCurrentCoro. - sCurrentCoro.reset(data->mPrev); + // data->mPrev, but this is our last chance to reset Current. + Current().reset(data->mPrev); } /***************************************************************************** @@ -282,7 +326,7 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name, mPrev(prev), mName(name), // Wrap the caller's callable in our toplevel() function so we can manage - // sCurrentCoro appropriately at startup and shutdown of each coroutine. + // Current appropriately at startup and shutdown of each coroutine. mCoro(boost::bind(toplevel, _1, this, callable), stacksize), // don't consume events unless specifically directed mConsuming(false), @@ -293,13 +337,13 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name, std::string LLCoros::launch(const std::string& prefix, const callable_t& callable) { std::string name(generateDistinctName(prefix)); - // pass the current value of sCurrentCoro as previous context - CoroData* newCoro = new CoroData(sCurrentCoro.get(), name, - callable, mStackSize); + Current current; + // pass the current value of Current as previous context + CoroData* newCoro = new CoroData(current, name, callable, mStackSize); // Store it in our pointer map mCoros.insert(name, newCoro); // also set it as current - sCurrentCoro.reset(newCoro); + current.reset(newCoro); /* Run the coroutine until its first wait, then return here */ (newCoro->mCoro)(std::nothrow); return name; diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 39316ed0e6..bbe2d22af4 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -35,8 +35,10 @@ #include #include #include +#include #include #include +#include "llcoro_get_id.h" // for friend declaration // forward-declare helper class namespace llcoro @@ -83,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; @@ -173,9 +176,8 @@ 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; bool cleanup(const LLSD&); struct CoroData; @@ -222,8 +224,22 @@ private: typedef boost::ptr_map CoroMap; CoroMap mCoros; - // identify the current coroutine's CoroData - static boost::thread_specific_ptr sCurrentCoro; + // Identify the current coroutine's CoroData. Use a little helper class so + // a caller can either use a temporary instance, or instantiate a named + // variable and access it multiple times. + class Current + { + public: + Current(); + + operator LLCoros::CoroData*() { return get(); } + LLCoros::CoroData* operator->() { return get(); } + LLCoros::CoroData* get() { return mCurrent->get(); } + void reset(LLCoros::CoroData* ptr) { mCurrent->reset(ptr); } + + private: + boost::thread_specific_ptr* mCurrent; + }; }; namespace llcoro @@ -231,7 +247,7 @@ namespace llcoro /// Instantiate one of these in a block surrounding any leaf point when /// control literally switches away from this coroutine. -class Suspending +class Suspending: boost::noncopyable { public: Suspending(); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f21c33a7c0..73ad9c33fd 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -243,6 +243,14 @@ namespace { namespace { std::string className(const std::type_info& type) + { + return LLError::Log::demangle(type.name()); + } +} // anonymous + +namespace LLError +{ + std::string Log::demangle(const char* mangled) { #ifdef __GNUC__ // GCC: type_info::name() returns a mangled class name,st demangle @@ -257,31 +265,34 @@ namespace // but gcc 3.3 libstc++'s implementation of demangling is broken // and fails without. - char* name = abi::__cxa_demangle(type.name(), + char* name = abi::__cxa_demangle(mangled, abi_name_buf, &abi_name_len, &status); // this call can realloc the abi_name_buf pointer (!) - return name ? name : type.name(); + return name ? name : mangled; #elif LL_WINDOWS // DevStudio: type_info::name() includes the text "class " at the start static const std::string class_prefix = "class "; - - std::string name = type.name(); - std::string::size_type p = name.find(class_prefix); - if (p == std::string::npos) + std::string name = mangled; + if (0 != name.compare(0, class_prefix.length(), class_prefix)) { + LL_DEBUGS() << "Did not see '" << class_prefix << "' prefix on '" + << name << "'" << LL_ENDL; return name; } - return name.substr(p + class_prefix.size()); + return name.substr(class_prefix.length()); -#else - return type.name(); +#else + return mangled; #endif } +} // LLError +namespace +{ std::string functionName(const std::string& preprocessor_name) { #if LL_WINDOWS @@ -368,9 +379,8 @@ namespace class Globals : public LLSingleton { + LLSINGLETON(Globals); public: - Globals(); - std::ostringstream messageStream; bool messageStreamInUse; @@ -443,11 +453,10 @@ namespace LLError class Settings : public LLSingleton { + LLSINGLETON(Settings); public: - Settings(); - SettingsConfigPtr getSettingsConfig(); - + void reset(); SettingsStoragePtr saveAndReset(); void restore(SettingsStoragePtr pSettingsStorage); @@ -455,7 +464,7 @@ namespace LLError private: SettingsConfigPtr mSettingsConfig; }; - + SettingsConfig::SettingsConfig() : LLRefCount(), mPrintLocation(false), @@ -480,8 +489,7 @@ namespace LLError mRecorders.clear(); } - Settings::Settings() - : LLSingleton(), + Settings::Settings(): mSettingsConfig(new SettingsConfig()) { } @@ -490,26 +498,31 @@ namespace LLError { return mSettingsConfig; } - + void Settings::reset() { Globals::getInstance()->invalidateCallSites(); mSettingsConfig = new SettingsConfig(); } - + SettingsStoragePtr Settings::saveAndReset() { SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); reset(); return oldSettingsConfig; } - + void Settings::restore(SettingsStoragePtr pSettingsStorage) { Globals::getInstance()->invalidateCallSites(); SettingsConfigPtr newSettingsConfig(dynamic_cast(pSettingsStorage.get())); mSettingsConfig = newSettingsConfig; } + + bool is_available() + { + return Settings::instanceExists() && Globals::instanceExists(); + } } namespace LLError diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 5c09ba2c9a..e74e9723a4 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -190,6 +190,7 @@ namespace LLError static std::ostringstream* out(); static void flush(std::ostringstream* out, char* message); static void flush(std::ostringstream*, const CallSite&); + static std::string demangle(const char* mangled); }; struct LL_COMMON_API CallSite diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 56ac52e5de..56e84f7172 100644 --- 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/llevents.h b/indra/llcommon/llevents.h index a3b9ec02e0..7cff7dfd45 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -229,7 +229,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 @@ -272,7 +272,6 @@ private: void unregister(const LLEventPump&); private: - LLEventPumps(); ~LLEventPumps(); testable: diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 3d3ef79562..bc73ef3501 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -239,7 +239,7 @@ int LLFile::close(LLFILE * file) } -int LLFile::remove(const std::string& filename) +int LLFile::remove(const std::string& filename, int supress_error) { #if LL_WINDOWS std::string utf8filename = filename; @@ -248,7 +248,7 @@ int LLFile::remove(const std::string& filename) #else int rc = ::remove(filename.c_str()); #endif - return warnif("remove", filename, rc); + return warnif("remove", filename, rc, supress_error); } int LLFile::rename(const std::string& filename, const std::string& newname) diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 315e18e4f2..37eb75881c 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -72,7 +72,7 @@ public: static int mkdir(const std::string& filename, int perms = 0700); static int rmdir(const std::string& filename); - static int remove(const std::string& filename); + static int remove(const std::string& filename, int supress_error = 0); static int rename(const std::string& filename,const std::string& newname); static bool copy(const std::string from, const std::string to); diff --git a/indra/llcommon/llheteromap.cpp b/indra/llcommon/llheteromap.cpp new file mode 100644 index 0000000000..7c19196e0c --- /dev/null +++ b/indra/llcommon/llheteromap.cpp @@ -0,0 +1,32 @@ +/** + * @file llheteromap.cpp + * @author Nat Goodspeed + * @date 2016-10-12 + * @brief Implementation for llheteromap. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llheteromap.h" +// STL headers +// std headers +// external library headers +// other Linden headers + +LLHeteroMap::~LLHeteroMap() +{ + // For each entry in our map, we must call its deleter, which is the only + // record we have of its original type. + for (TypeMap::iterator mi(mMap.begin()), me(mMap.end()); mi != me; ++mi) + { + // mi->second is the std::pair; mi->second.first is the void*; + // mi->second.second points to the deleter function + (mi->second.second)(mi->second.first); + mi->second.first = NULL; + } +} diff --git a/indra/llcommon/llheteromap.h b/indra/llcommon/llheteromap.h new file mode 100644 index 0000000000..9d6f303d08 --- /dev/null +++ b/indra/llcommon/llheteromap.h @@ -0,0 +1,95 @@ +/** + * @file llheteromap.h + * @author Nat Goodspeed + * @date 2016-10-12 + * @brief Map capable of storing objects of diverse types, looked up by type. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLHETEROMAP_H) +#define LL_LLHETEROMAP_H + +#include +#include // std::pair +#include + +/** + * LLHeteroMap addresses an odd requirement. Usually when you want to put + * objects of different classes into a runtime collection of any kind, you + * derive them all from a common base class and store pointers to that common + * base class. + * + * LLInitParam::BaseBlock uses disturbing raw-pointer arithmetic to find data + * members in its subclasses. It seems that no BaseBlock subclass can be + * stored in a polymorphic class of any kind: the presence of a vtbl pointer + * in the layout silently throws off the reinterpret_cast arithmetic. Bad + * Things result. (Many thanks to Nicky D for this analysis!) + * + * LLHeteroMap collects objects WITHOUT a common base class, retrieves them by + * object type and destroys them when the LLHeteroMap is destroyed. + */ +class LLHeteroMap +{ +public: + ~LLHeteroMap(); + + /// find or create + template + T& obtain() + { + // Look up map entry by typeid(T). We don't simply use mMap[typeid(T)] + // because that requires default-constructing T on every lookup. For + // some kinds of T, that could be expensive. + TypeMap::iterator found = mMap.find(&typeid(T)); + if (found == mMap.end()) + { + // Didn't find typeid(T). Create an entry. Because we're storing + // only a void* in the map, discarding type information, make sure + // we capture that type information in our deleter. + void* ptr = new T(); + void (*dlfn)(void*) = &deleter; + std::pair inserted = + mMap.insert(TypeMap::value_type(&typeid(T), + TypeMap::mapped_type(ptr, dlfn))); + // Okay, now that we have an entry, claim we found it. + found = inserted.first; + } + // found->second is the std::pair; second.first is the void* + // pointer to the object in question. Cast it to correct type and + // dereference it. + return *(static_cast(found->second.first)); + } + +private: + template + static + void deleter(void* p) + { + delete static_cast(p); + } + + // Comparing two std::type_info* values is tricky, because the standard + // does not guarantee that there will be only one type_info instance for a + // given type. In other words, &typeid(A) in one part of the program may + // not always equal &typeid(A) in some other part. Use special comparator. + struct type_info_ptr_comp + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) + { + return lhs->before(*rhs); + } + }; + + // What we actually store is a map from std::type_info (permitting lookup + // by object type) to a void* pointer to the object PLUS its deleter. + typedef std::map< + const std::type_info*, std::pair, + type_info_ptr_comp> + TypeMap; + TypeMap mMap; +}; + +#endif /* ! defined(LL_LLHETEROMAP_H) */ diff --git a/indra/llcommon/llinitdestroyclass.cpp b/indra/llcommon/llinitdestroyclass.cpp new file mode 100644 index 0000000000..e6382a7924 --- /dev/null +++ b/indra/llcommon/llinitdestroyclass.cpp @@ -0,0 +1,30 @@ +/** + * @file llinitdestroyclass.cpp + * @author Nat Goodspeed + * @date 2016-08-30 + * @brief Implementation for llinitdestroyclass. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llinitdestroyclass.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" + +void LLCallbackRegistry::fireCallbacks() const +{ + for (FuncList::const_iterator fi = mCallbacks.begin(), fe = mCallbacks.end(); + fi != fe; ++fi) + { + LL_INFOS("LLInitDestroyClass") << "calling " << fi->first << "()" << LL_ENDL; + fi->second(); + } +} diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h new file mode 100644 index 0000000000..5f979614fe --- /dev/null +++ b/indra/llcommon/llinitdestroyclass.h @@ -0,0 +1,175 @@ +/** + * @file llinitdestroyclass.h + * @author Nat Goodspeed + * @date 2015-05-27 + * @brief LLInitClass / LLDestroyClass mechanism + * + * The LLInitClass template, extracted from llui.h, ensures that control will + * reach a static initClass() method. LLDestroyClass does the same for a + * static destroyClass() method. + * + * The distinguishing characteristics of these templates are: + * + * - All LLInitClass::initClass() methods are triggered by an explicit call + * to LLInitClassList::instance().fireCallbacks(). Presumably this call + * happens sometime after all static objects in the program have been + * initialized. In other words, each LLInitClass::initClass() method + * should be able to make some assumptions about global program state. + * + * - Similarly, LLDestroyClass::destroyClass() methods are triggered by + * LLDestroyClassList::instance().fireCallbacks(). Again, presumably this + * happens at a well-defined moment in the program's shutdown sequence. + * + * - The initClass() calls happen in an unspecified sequence. You may not rely + * on the relative ordering of LLInitClass::initClass() versus another + * LLInitClass::initClass() method. If you need such a guarantee, use + * LLSingleton instead and make the dependency explicit. + * + * - Similarly, LLDestroyClass::destroyClass() may happen either before or + * after LLDestroyClass::destroyClass(). You cannot rely on that order. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLINITDESTROYCLASS_H) +#define LL_LLINITDESTROYCLASS_H + +#include "llsingleton.h" +#include +#include +#include +#include // std::pair + +/** + * LLCallbackRegistry is an implementation detail base class for + * LLInitClassList and LLDestroyClassList. It accumulates the initClass() or + * destroyClass() callbacks for registered classes. + */ +class LLCallbackRegistry +{ +public: + typedef boost::function func_t; + + void registerCallback(const std::string& name, const func_t& func) + { + mCallbacks.push_back(FuncList::value_type(name, func)); + } + + void fireCallbacks() const; + +private: + // Arguably this should be a boost::signals2::signal, which is, after all, + // a sequence of callables. We manage it by hand so we can log a name for + // each registered function we call. + typedef std::vector< std::pair > FuncList; + FuncList mCallbacks; +}; + +/** + * LLInitClassList is the LLCallbackRegistry for LLInitClass. It stores the + * registered initClass() methods. It must be an LLSingleton because + * LLInitClass registers its initClass() method at static construction time + * (before main()), requiring LLInitClassList to be fully constructed on + * demand regardless of module initialization order. + */ +class LLInitClassList : + public LLCallbackRegistry, + public LLSingleton +{ + LLSINGLETON_EMPTY_CTOR(LLInitClassList); +}; + +/** + * LLDestroyClassList is the LLCallbackRegistry for LLDestroyClass. It stores + * the registered destroyClass() methods. It must be an LLSingleton because + * LLDestroyClass registers its destroyClass() method at static construction + * time (before main()), requiring LLDestroyClassList to be fully constructed + * on demand regardless of module initialization order. + */ +class LLDestroyClassList : + public LLCallbackRegistry, + public LLSingleton +{ + LLSINGLETON_EMPTY_CTOR(LLDestroyClassList); +}; + +/** + * LLRegisterWith is an implementation detail for LLInitClass and + * LLDestroyClass. It is intended to be used as a static class member whose + * constructor registers the specified callback with the LLMumbleClassList + * singleton registry specified as the template argument. + */ +template +class LLRegisterWith +{ +public: + LLRegisterWith(const std::string& name, const LLCallbackRegistry::func_t& func) + { + T::instance().registerCallback(name, func); + } + + // this avoids a MSVC bug where non-referenced static members are "optimized" away + // even if their constructors have side effects + S32 reference() + { + S32 dummy; + dummy = 0; + return dummy; + } +}; + +/** + * Derive MyClass from LLInitClass (the Curiously Recurring Template + * Pattern) to ensure that the static method MyClass::initClass() will be + * called (along with all other LLInitClass subclass initClass() methods) + * when someone calls LLInitClassList::instance().fireCallbacks(). This gives + * the application specific control over the timing of all such + * initializations, without having to insert calls for every such class into + * generic application code. + */ +template +class LLInitClass +{ +public: + LLInitClass() { sRegister.reference(); } + + // When this static member is initialized, the subclass initClass() method + // is registered on LLInitClassList. See sRegister definition below. + static LLRegisterWith sRegister; +}; + +/** + * Derive MyClass from LLDestroyClass (the Curiously Recurring + * Template Pattern) to ensure that the static method MyClass::destroyClass() + * will be called (along with other LLDestroyClass subclass destroyClass() + * methods) when someone calls LLDestroyClassList::instance().fireCallbacks(). + * This gives the application specific control over the timing of all such + * cleanup calls, without having to insert calls for every such class into + * generic application code. + */ +template +class LLDestroyClass +{ +public: + LLDestroyClass() { sRegister.reference(); } + + // When this static member is initialized, the subclass destroyClass() + // method is registered on LLInitClassList. See sRegister definition + // below. + static LLRegisterWith sRegister; +}; + +// Here's where LLInitClass specifies the subclass initClass() method. +template +LLRegisterWith +LLInitClass::sRegister(std::string(typeid(T).name()) + "::initClass", + &T::initClass); +// Here's where LLDestroyClass specifies the subclass destroyClass() method. +template +LLRegisterWith +LLDestroyClass::sRegister(std::string(typeid(T).name()) + "::destroyClass", + &T::destroyClass); + +#endif /* ! defined(LL_LLINITDESTROYCLASS_H) */ diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index aa2f4eb289..1d104cf55d 100644 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -193,7 +193,12 @@ namespace LLInitParam { if (!silent) { - p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str())); + std::string file_name = p.getCurrentFileName(); + if(!file_name.empty()) + { + file_name = "in file: " + file_name; + } + p.parserWarning(llformat("Failed to parse parameter \"%s\" %s", p.getCurrentElementName().c_str(), file_name.c_str())); } return false; } diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index c65b05f610..f1f4226c40 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -551,6 +551,7 @@ namespace LLInitParam } virtual std::string getCurrentElementName() = 0; + virtual std::string getCurrentFileName() = 0; virtual void parserWarning(const std::string& message); virtual void parserError(const std::string& message); void setParseSilently(bool silent) { mParseSilently = silent; } diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 1fc821d9a9..16fc365da1 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -40,7 +40,7 @@ LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ; /*static*/ -void LLMetricPerformanceTesterBasic::cleanClass() +void LLMetricPerformanceTesterBasic::cleanupClass() { for (name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter) { diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 1a18cdf36f..e6b46be1cf 100644 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h @@ -156,7 +156,7 @@ public: /** * @brief Delete all testers and reset the tester map */ - static void cleanClass() ; + static void cleanupClass() ; private: // Add a tester to the map. Returns false if adding fails. diff --git a/indra/llcommon/llpounceable.h b/indra/llcommon/llpounceable.h new file mode 100644 index 0000000000..0421ce966a --- /dev/null +++ b/indra/llcommon/llpounceable.h @@ -0,0 +1,216 @@ +/** + * @file llpounceable.h + * @author Nat Goodspeed + * @date 2015-05-22 + * @brief LLPounceable is tangentially related to a future: it's a holder for + * a value that may or may not exist yet. Unlike a future, though, + * LLPounceable freely allows reading the held value. (If the held + * type T does not have a distinguished "empty" value, consider using + * LLPounceable>.) + * + * LLPounceable::callWhenReady() is this template's claim to fame. It + * allows its caller to "pounce" on the held value as soon as it + * becomes non-empty. Call callWhenReady() with any C++ callable + * accepting T. If the held value is already non-empty, callWhenReady() + * will immediately call the callable with the held value. If the held + * value is empty, though, callWhenReady() will enqueue the callable + * for later. As soon as LLPounceable is assigned a non-empty held + * value, it will flush the queue of deferred callables. + * + * Consider a global LLMessageSystem* gMessageSystem. Message system + * initialization happens at a very specific point during viewer + * initialization. Other subsystems want to register callbacks on the + * LLMessageSystem instance as soon as it's initialized, but their own + * initialization may precede that. If we define gMessageSystem to be + * an LLPounceable, a subsystem can use + * callWhenReady() to either register immediately (if gMessageSystem + * is already up and runnning) or register as soon as gMessageSystem + * is set with a new, initialized instance. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLPOUNCEABLE_H) +#define LL_LLPOUNCEABLE_H + +#include "llsingleton.h" +#include +#include +#include +#include +#include +#include + +// Forward declare the user template, since we want to be able to point to it +// in some of its implementation classes. +template +class LLPounceable; + +template +struct LLPounceableTraits +{ + // Our "queue" is a signal object with correct signature. + typedef boost::signals2::signal::param_type)> signal_t; + // Call callWhenReady() with any callable accepting T. + typedef typename signal_t::slot_type func_t; + // owner pointer type + typedef LLPounceable* owner_ptr; +}; + +// Tag types distinguish the two different implementations of LLPounceable's +// queue. +struct LLPounceableQueue {}; +struct LLPounceableStatic {}; + +// generic LLPounceableQueueImpl deliberately omitted: only the above tags are +// legal +template +class LLPounceableQueueImpl; + +// The implementation selected by LLPounceableStatic uses an LLSingleton +// because we can't count on a data member queue being initialized at the time +// we start getting callWhenReady() calls. This is that LLSingleton. +template +class LLPounceableQueueSingleton: + public LLSingleton > +{ + LLSINGLETON_EMPTY_CTOR(LLPounceableQueueSingleton); + + typedef LLPounceableTraits traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + + // For a given held type T, every LLPounceable + // instance will call on the SAME LLPounceableQueueSingleton instance -- + // given how class statics work. We must keep a separate queue for each + // LLPounceable instance. Use a hash map for that. + typedef boost::unordered_map map_t; + +public: + // Disambiguate queues belonging to different LLPounceables. + signal_t& get(owner_ptr owner) + { + // operator[] has find-or-create semantics -- just what we want! + return mMap[owner]; + } + +private: + map_t mMap; +}; + +// LLPounceableQueueImpl that uses the above LLSingleton +template +class LLPounceableQueueImpl +{ +public: + typedef LLPounceableTraits traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + + signal_t& get(owner_ptr owner) const + { + // this Impl contains nothing; it delegates to the Singleton + return LLPounceableQueueSingleton::instance().get(owner); + } +}; + +// The implementation selected by LLPounceableQueue directly contains the +// queue of interest, suitable for an LLPounceable we can trust to be fully +// initialized when it starts getting callWhenReady() calls. +template +class LLPounceableQueueImpl +{ +public: + typedef LLPounceableTraits traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + + signal_t& get(owner_ptr) + { + return mQueue; + } + +private: + signal_t mQueue; +}; + +// LLPounceable is for an LLPounceable instance on the heap or the stack. +// LLPounceable is for a static LLPounceable instance. +template +class LLPounceable: public boost::noncopyable +{ +private: + typedef LLPounceableTraits traits; + typedef typename traits::owner_ptr owner_ptr; + typedef typename traits::signal_t signal_t; + +public: + typedef typename traits::func_t func_t; + + // By default, both the initial value and the distinguished empty value + // are a default-constructed T instance. However you can explicitly + // specify each. + LLPounceable(typename boost::call_traits::value_type init =boost::value_initialized(), + typename boost::call_traits::param_type empty=boost::value_initialized()): + mHeld(init), + mEmpty(empty) + {} + + // make read access to mHeld as cheap and transparent as possible + operator T () const { return mHeld; } + typename boost::remove_pointer::type operator*() const { return *mHeld; } + typename boost::call_traits::value_type operator->() const { return mHeld; } + // uncomment 'explicit' as soon as we allow C++11 compilation + /*explicit*/ operator bool() const { return bool(mHeld); } + bool operator!() const { return ! mHeld; } + + // support both assignment (dumb ptr idiom) and reset() (smart ptr) + void operator=(typename boost::call_traits::param_type value) + { + reset(value); + } + + void reset(typename boost::call_traits::param_type value) + { + mHeld = value; + // If this new value is non-empty, flush anything pending in the queue. + if (mHeld != mEmpty) + { + signal_t& signal(get_signal()); + signal(mHeld); + signal.disconnect_all_slots(); + } + } + + // our claim to fame + void callWhenReady(const func_t& func) + { + if (mHeld != mEmpty) + { + // If the held value is already non-empty, immediately call func() + func(mHeld); + } + else + { + // Held value still empty, queue func() for later. By default, + // connect() enqueues slots in FIFO order. + get_signal().connect(func); + } + } + +private: + signal_t& get_signal() { return mQueue.get(this); } + + // Store both the current and the empty value. + // MAYBE: Might be useful to delegate to LLPounceableTraits the meaning of + // testing for "empty." For some types we want operator!(); for others we + // want to compare to a distinguished value. + typename boost::call_traits::value_type mHeld, mEmpty; + // This might either contain the queue (LLPounceableQueue) or delegate to + // an LLSingleton (LLPounceableStatic). + LLPounceableQueueImpl mQueue; +}; + +#endif /* ! defined(LL_LLPOUNCEABLE_H) */ diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 29950c108d..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; @@ -269,7 +272,7 @@ public: ~ScopedRegistrar() { - if (!singleton_t::destroyed()) + if (singleton_t::instanceExists()) { popScope(); } diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h index 09f1bdf1e3..93910b70ae 100644 --- a/indra/llcommon/llsdparam.h +++ b/indra/llcommon/llsdparam.h @@ -66,6 +66,7 @@ public: } /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName(){ return LLStringUtil::null; } private: void writeSDImpl(LLSD& sd, diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index b24e303e7b..9025e53bb2 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -24,9 +24,446 @@ * $/LicenseInfo$ */ -// Get rid of LNK4221 linker warning since we don't run the unit tests anyway -//#include "linden_common.h" +#include "linden_common.h" +#include "llsingleton.h" -//#include "llsingleton.h" +#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 +#include +namespace { +void log(LLError::ELevel level, + 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 +// 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 +{ + LLSINGLETON_EMPTY_CTOR(MasterList); + +public: + // No need to make this private with accessors; nobody outside this source + // file can see it. + + // 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()]; + } + + void cleanup_initializing_() + { + InitializingMap::iterator found = mInitializing.find(llcoro::get_id()); + if (found != mInitializing.end()) + { + mInitializing.erase(found); + } + } +}; + +//static +LLSingletonBase::list_t& LLSingletonBase::get_master() +{ + return LLSingletonBase::MasterList::instance().mMaster; +} + +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); +} + +//static +LLSingletonBase::list_t& LLSingletonBase::get_initializing() +{ + return LLSingletonBase::MasterList::instance().get_initializing_(); +} + +//static +LLSingletonBase::list_t& LLSingletonBase::get_initializing_from(MasterList* master) +{ + return master->get_initializing_(); +} + +LLSingletonBase::~LLSingletonBase() {} + +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()"); + } + + // Now we know list.back() exists: capture it + LLSingletonBase* back(list.back()); + // 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: ", + demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ", + demangle(typeid(*back).name()).c_str()); + } + + // 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(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(). + 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. + 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 + // 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(), + demangle(typeid(*this).name()).c_str(), ""); + } + 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. + LLSingletonBase* current(initializing.back()); + if (current->mDepends.insert(this).second) + { + // only log the FIRST time we hit this dependency! + logdebugs(demangle(typeid(*current).name()).c_str(), + " depends on ", demangle(typeid(*this).name()).c_str()); + } + } + } +} + +//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; + + logdebugs("calling ", + demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()"); + try + { + sp->cleanupSingleton(); + } + catch (const std::exception& e) + { + logwarns("Exception in ", demangle(typeid(*sp).name()).c_str(), + "::cleanupSingleton(): ", e.what()); + } + catch (...) + { + logwarns("Unknown exception in ", demangle(typeid(*sp).name()).c_str(), + "::cleanupSingleton()"); + } + } + } +} + +//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 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.c_str(), "::mDeleteSingleton not initialized!"); + } + else + { + // properly initialized: call it. + logdebugs("calling ", name.c_str(), "::deleteSingleton()"); + // From this point on, DO NOT DEREFERENCE sp! + sp->mDeleteSingleton(); + } + } + catch (const std::exception& e) + { + logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what()); + } + catch (...) + { + logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()"); + } + } +} + +/*------------------------ 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 -----------------------------*/ +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) +{ + // 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 + // around and around we go. + if (LLError::is_available()) + { + LL_VLOGS(level, "LLSingleton") << 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; + } +} + +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 +void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4) +{ + 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) +{ + return LLError::Log::demangle(mangled); +} diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 6e6291a165..1b915dfd6e 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -25,188 +25,495 @@ #ifndef LLSINGLETON_H #define LLSINGLETON_H -#include "llerror.h" // *TODO: eliminate this - -#include #include +#include +#include +#include +#include +#include -// LLSingleton implements the getInstance() method part of the Singleton -// pattern. It can't make the derived class constructors protected, though, so -// you have to do that yourself. -// -// There are two ways to use LLSingleton. The first way is to inherit from it -// while using the typename that you'd like to be static as the template -// parameter, like so: -// -// class Foo: public LLSingleton{}; -// -// Foo& instance = Foo::instance(); -// -// The second way is to use the singleton class directly, without inheritance: -// -// typedef LLSingleton FooSingleton; -// -// Foo& instance = FooSingleton::instance(); -// -// In this case, the class being managed as a singleton needs to provide an -// initSingleton() method since the LLSingleton virtual method won't be -// available -// -// As currently written, it is not thread-safe. - -template -class LLSingleton : private boost::noncopyable +class LLSingletonBase: private boost::noncopyable +{ +public: + class MasterList; + class MasterRefcount; + typedef boost::intrusive_ptr ref_ptr_t; + +private: + // All existing LLSingleton instances are tracked in this master list. + typedef std::list list_t; + static list_t& get_master(); + // 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(); + + bool mCleaned; // cleanupSingleton() has been called + // we directly depend on these other LLSingletons + typedef boost::unordered_set set_t; + set_t mDepends; + +protected: + typedef enum e_init_state + { + UNINITIALIZED = 0, // must be default-initialized state + CONSTRUCTING, + INITIALIZING, + INITIALIZED, + 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 tag for various purposes. + template + LLSingletonBase(tag); + virtual ~LLSingletonBase(); + + // Every new LLSingleton should be added to/removed from the master list + void add_master(); + void remove_master(); + // with a little help from our friends. + template friend struct LLSingleton_manage_master; + + // Maintain a stack of the LLSingleton subclass instance currently being + // initialized. We use this to notice direct dependencies: we want to know + // if A requires B. We deduce a dependency if while initializing A, + // control reaches B::getInstance(). + // We want &A to be at the top of that stack during both A::A() and + // A::initSingleton(), since a call to B::getInstance() might occur during + // either. + // Unfortunately the desired timespan does not correspond neatly with a + // 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(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(list_t& initializing, EInitState); + + // delegate LL_ERRS() logging to llsingleton.cpp + 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="", const char* p4=""); + static std::string demangle(const char* mangled); + + // obtain canonical ref_ptr_t + static ref_ptr_t get_master_refcount(); + + // Default methods in case subclass doesn't declare them. + virtual void initSingleton() {} + virtual void cleanupSingleton() {} + + // deleteSingleton() isn't -- and shouldn't be -- a virtual method. It's a + // class static. However, given only Foo*, deleteAll() does need to be + // able to reach Foo::deleteSingleton(). Make LLSingleton (which declares + // deleteSingleton()) store a pointer here. Since we know it's a static + // class method, a classic-C function pointer will do. + void (*mDeleteSingleton)(); + +public: + /** + * Call this to call the cleanupSingleton() method for every LLSingleton + * constructed since the start of the last cleanupAll() call. (Any + * LLSingleton constructed DURING a cleanupAll() call won't be cleaned up + * until the next cleanupAll() call.) cleanupSingleton() neither deletes + * nor destroys its LLSingleton; therefore it's safe to include logic that + * might take significant realtime or even throw an exception. + * + * The most important property of cleanupAll() is that cleanupSingleton() + * methods are called in dependency order, leaf classes last. Thus, given + * two LLSingleton subclasses A and B, if A's dependency on B is properly + * expressed as a B::getInstance() or B::instance() call during either + * A::A() or A::initSingleton(), B will be cleaned up after A. + * + * If a cleanupSingleton() method throws an exception, the exception is + * logged, but cleanupAll() attempts to continue calling the rest of the + * cleanupSingleton() methods. + */ + static void cleanupAll(); + /** + * Call this to call the deleteSingleton() method for every LLSingleton + * constructed since the start of the last deleteAll() call. (Any + * LLSingleton constructed DURING a deleteAll() call won't be cleaned up + * until the next deleteAll() call.) deleteSingleton() deletes and + * destroys its LLSingleton. Any cleanup logic that might take significant + * realtime -- or throw an exception -- must not be placed in your + * LLSingleton's destructor, but rather in its cleanupSingleton() method. + * + * The most important property of deleteAll() is that deleteSingleton() + * methods are called in dependency order, leaf classes last. Thus, given + * two LLSingleton subclasses A and B, if A's dependency on B is properly + * expressed as a B::getInstance() or B::instance() call during either + * A::A() or A::initSingleton(), B will be cleaned up after A. + * + * If a deleteSingleton() method throws an exception, the exception is + * logged, but deleteAll() attempts to continue calling the rest of the + * deleteSingleton() methods. + */ + static void deleteAll(); +}; + +// support ref_ptr_t +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 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. +template <> +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 + * you have to do that yourself. + * + * Derive your class from LLSingleton, passing your subclass name as + * LLSingleton's template parameter, like so: + * + * class Foo: public LLSingleton + * { + * // use this macro at start of every LLSingleton subclass + * LLSINGLETON(Foo); + * public: + * // ... + * }; + * + * Foo& instance = Foo::instance(); + * + * LLSingleton recognizes a couple special methods in your derived class. + * + * If you override LLSingleton::initSingleton(), your method will be called + * immediately after the instance is constructed. This is useful for breaking + * circular dependencies: if you find that your LLSingleton subclass + * constructor references other LLSingleton subclass instances in a chain + * leading back to yours, move the instance reference from your constructor to + * your initSingleton() method. + * + * If you override LLSingleton::cleanupSingleton(), your method will be + * called if someone calls LLSingletonBase::cleanupAll(). The significant part + * of this promise is that cleanupAll() will call individual + * cleanupSingleton() methods in reverse dependency order. + * + * That is, consider LLSingleton subclasses C, B and A. A depends on B, which + * in turn depends on C. These dependencies are expressed as calls to + * B::instance() or B::getInstance(), and C::instance() or C::getInstance(). + * It shouldn't matter whether these calls appear in A::A() or + * A::initSingleton(), likewise B::B() or B::initSingleton(). + * + * We promise that if you later call LLSingletonBase::cleanupAll(): + * 1. A::cleanupSingleton() will be called before + * 2. B::cleanupSingleton(), which will be called before + * 3. C::cleanupSingleton(). + * Put differently, if your LLSingleton subclass constructor or + * initSingleton() method explicitly depends on some other LLSingleton + * subclass, you may continue to rely on that other subclass in your + * cleanupSingleton() method. + * + * We introduce a special cleanupSingleton() method because cleanupSingleton() + * operations can involve nontrivial realtime, or might throw an exception. A + * destructor should do neither! + * + * If your cleanupSingleton() method throws an exception, we log that + * exception but proceed with the remaining cleanupSingleton() calls. + * + * Similarly, if at some point you call LLSingletonBase::deleteAll(), all + * remaining LLSingleton instances will be destroyed in dependency order. (Or + * call MySubclass::deleteSingleton() to specifically destroy the canonical + * MySubclass instance.) + * + * As currently written, LLSingleton is not thread-safe. + */ +template +class LLSingleton : public LLSingletonBase { - private: - typedef enum e_init_state - { - UNINITIALIZED, - CONSTRUCTING, - INITIALIZING, - INITIALIZED, - DELETED - } EInitState; - static DERIVED_TYPE* constructSingleton() { return new DERIVED_TYPE(); } - - // stores pointer to singleton instance - struct SingletonLifetimeManager - { - SingletonLifetimeManager() - { - construct(); - } - static void construct() - { - sData.mInitState = CONSTRUCTING; - sData.mInstance = constructSingleton(); - sData.mInitState = INITIALIZING; - } + // 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 + { + SingletonLifetimeManager(): + mMasterRefcount(LLSingletonBase::get_master_refcount()) + { + construct(); + } + + static void construct() + { + sData.mInitState = CONSTRUCTING; + sData.mInstance = constructSingleton(); + sData.mInitState = INITIALIZING; + } + + ~SingletonLifetimeManager() + { + // The dependencies between LLSingletons, and the arbitrary order + // of static-object destruction, mean that we DO NOT WANT this + // destructor to delete this LLSingleton. This destructor will run + // without regard to any other LLSingleton whose cleanup might + // depend on its existence. What we really want is to count the + // runtime's attempts to cleanup LLSingleton static data -- and on + // the very last one, call LLSingletonBase::deleteAll(). That + // method will properly honor cross-LLSingleton dependencies. This + // is why we store an intrusive_ptr to a MasterRefcount: our + // ref_ptr_t member counts SingletonLifetimeManager instances. + // Once the runtime destroys the last of these, THEN we can delete + // every remaining LLSingleton. + } + + LLSingletonBase::ref_ptr_t mMasterRefcount; + }; + +protected: + // 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 + mDeleteSingleton = &deleteSingleton; + + // add this new instance to the master list + LLSingleton_manage_master().add(this); + } - ~SingletonLifetimeManager() - { - if (sData.mInitState != DELETED) - { - deleteSingleton(); - } - } - }; - public: - virtual ~LLSingleton() - { - sData.mInstance = NULL; - sData.mInitState = DELETED; - } + virtual ~LLSingleton() + { + // remove this instance from the master list + LLSingleton_manage_master().remove(this); + sData.mInstance = NULL; + sData.mInitState = DELETED; + } - /** - * @brief Immediately delete the singleton. - * - * A subsequent call to LLProxy::getInstance() will construct a new - * instance of the class. - * - * LLSingletons are normally destroyed after main() has exited and the C++ - * runtime is cleaning up statically-constructed objects. Some classes - * derived from LLSingleton have objects that are part of a runtime system - * that is terminated before main() exits. Calling the destructor of those - * objects after the termination of their respective systems can cause - * crashes and other problems during termination of the project. Using this - * method to destroy the singleton early can prevent these crashes. - * - * An example where this is needed is for a LLSingleton that has an APR - * object as a member that makes APR calls on destruction. The APR system is - * shut down explicitly before main() exits. This causes a crash on exit. - * Using this method before the call to apr_terminate() and NOT calling - * getInstance() again will prevent the crash. - */ - static void deleteSingleton() - { - delete sData.mInstance; - sData.mInstance = NULL; - sData.mInitState = DELETED; - } + /** + * @brief Immediately delete the singleton. + * + * A subsequent call to LLProxy::getInstance() will construct a new + * instance of the class. + * + * Without an explicit call to LLSingletonBase::deleteAll(), LLSingletons + * are implicitly destroyed after main() has exited and the C++ runtime is + * cleaning up statically-constructed objects. Some classes derived from + * LLSingleton have objects that are part of a runtime system that is + * terminated before main() exits. Calling the destructor of those objects + * after the termination of their respective systems can cause crashes and + * other problems during termination of the project. Using this method to + * destroy the singleton early can prevent these crashes. + * + * An example where this is needed is for a LLSingleton that has an APR + * object as a member that makes APR calls on destruction. The APR system is + * shut down explicitly before main() exits. This causes a crash on exit. + * Using this method before the call to apr_terminate() and NOT calling + * getInstance() again will prevent the crash. + */ + static void deleteSingleton() + { + delete sData.mInstance; + sData.mInstance = NULL; + sData.mInitState = DELETED; + } + static DERIVED_TYPE* getInstance() + { + static SingletonLifetimeManager sLifeTimeMgr; - static DERIVED_TYPE* getInstance() - { - static SingletonLifetimeManager sLifeTimeMgr; + switch (sData.mInitState) + { + case UNINITIALIZED: + // should never be uninitialized at this point + logerrs("Uninitialized singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str()); + return NULL; - switch (sData.mInitState) - { - case UNINITIALIZED: - // should never be uninitialized at this point - llassert(false); - return NULL; - case CONSTRUCTING: - LL_ERRS() << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << LL_ENDL; - return NULL; - case INITIALIZING: - // go ahead and flag ourselves as initialized so we can be reentrant during initialization - sData.mInitState = INITIALIZED; - // initialize singleton after constructing it so that it can reference other singletons which in turn depend on it, - // thus breaking cyclic dependencies - sData.mInstance->initSingleton(); - return sData.mInstance; - case INITIALIZED: - return sData.mInstance; - case DELETED: - LL_WARNS() << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << LL_ENDL; - SingletonLifetimeManager::construct(); - // same as first time construction - sData.mInitState = INITIALIZED; - sData.mInstance->initSingleton(); - return sData.mInstance; - } + case CONSTRUCTING: + logerrs("Tried to access singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str(), + " from singleton constructor!"); + return NULL; - return NULL; - } + case INITIALIZING: + // go ahead and flag ourselves as initialized so we can be + // reentrant during initialization + sData.mInitState = INITIALIZED; + // initialize singleton after constructing it so that it can + // reference other singletons which in turn depend on it, thus + // breaking cyclic dependencies + sData.mInstance->initSingleton(); + // pop this off stack of initializing singletons + LLSingleton_manage_master().pop_initializing(sData.mInstance); + break; - static DERIVED_TYPE* getIfExists() - { - return sData.mInstance; - } + case INITIALIZED: + break; - // Reference version of getInstance() - // Preferred over getInstance() as it disallows checking for NULL - static DERIVED_TYPE& instance() - { - return *getInstance(); - } - - // Has this singleton been created uet? - // Use this to avoid accessing singletons before the can safely be constructed - static bool instanceExists() - { - return sData.mInitState == INITIALIZED; - } - - // Has this singleton already been deleted? - // Use this to avoid accessing singletons from a static object's destructor - static bool destroyed() - { - return sData.mInitState == DELETED; - } + case DELETED: + logwarns("Trying to access deleted singleton ", + demangle(typeid(DERIVED_TYPE).name()).c_str(), + " -- creating new instance"); + SingletonLifetimeManager::construct(); + // same as first time construction + sData.mInitState = INITIALIZED; + sData.mInstance->initSingleton(); + // pop this off stack of initializing singletons + LLSingleton_manage_master().pop_initializing(sData.mInstance); + break; + } + + // By this point, if DERIVED_TYPE was pushed onto the initializing + // stack, it has been popped off. So the top of that stack, if any, is + // 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( + LLSingleton_manage_master().get_initializing(sData.mInstance), + sData.mInitState); + return sData.mInstance; + } + + // Reference version of getInstance() + // Preferred over getInstance() as it disallows checking for NULL + static DERIVED_TYPE& instance() + { + return *getInstance(); + } + + // Has this singleton been created yet? + // Use this to avoid accessing singletons before they can safely be constructed. + static bool instanceExists() + { + return sData.mInitState == INITIALIZED; + } private: - - virtual void initSingleton() {} - - struct SingletonData - { - // explicitly has a default constructor so that member variables are zero initialized in BSS - // and only changed by singleton logic, not constructor running during startup - EInitState mInitState; - DERIVED_TYPE* mInstance; - }; - static SingletonData sData; + struct SingletonData + { + // explicitly has a default constructor so that member variables are zero initialized in BSS + // and only changed by singleton logic, not constructor running during startup + EInitState mInitState; + DERIVED_TYPE* mInstance; + }; + static SingletonData sData; }; 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/llheteromap_test.cpp b/indra/llcommon/tests/llheteromap_test.cpp new file mode 100644 index 0000000000..686bffb878 --- /dev/null +++ b/indra/llcommon/tests/llheteromap_test.cpp @@ -0,0 +1,163 @@ +/** + * @file llheteromap_test.cpp + * @author Nat Goodspeed + * @date 2016-10-12 + * @brief Test for llheteromap. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llheteromap.h" +// STL headers +#include +// std headers +// external library headers + +// (pacify clang) +std::ostream& operator<<(std::ostream& out, const std::set& strset); +// other Linden headers +#include "../test/lltut.h" + +static std::string clog; +static std::set dlog; + +// want to be able to use ensure_equals() on a set +std::ostream& operator<<(std::ostream& out, const std::set& strset) +{ + out << '{'; + const char* delim = ""; + for (std::set::const_iterator si(strset.begin()), se(strset.end()); + si != se; ++si) + { + out << delim << '"' << *si << '"'; + delim = ", "; + } + out << '}'; + return out; +} + +// unrelated test classes +struct Chalk +{ + int dummy; + std::string name; + + Chalk(): + dummy(0) + { + clog.append("a"); + } + + ~Chalk() + { + dlog.insert("a"); + } + +private: + Chalk(const Chalk&); // no implementation +}; + +struct Cheese +{ + std::string name; + + Cheese() + { + clog.append("e"); + } + + ~Cheese() + { + dlog.insert("e"); + } + +private: + Cheese(const Cheese&); // no implementation +}; + +struct Chowdah +{ + char displace[17]; + std::string name; + + Chowdah() + { + displace[0] = '\0'; + clog.append("o"); + } + + ~Chowdah() + { + dlog.insert("o"); + } + +private: + Chowdah(const Chowdah&); // no implementation +}; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llheteromap_data + { + llheteromap_data() + { + clog.erase(); + dlog.clear(); + } + }; + typedef test_group llheteromap_group; + typedef llheteromap_group::object object; + llheteromap_group llheteromapgrp("llheteromap"); + + template<> template<> + void object::test<1>() + { + set_test_name("create, get, delete"); + + { + LLHeteroMap map; + + { + // create each instance + Chalk& chalk = map.obtain(); + chalk.name = "Chalk"; + + Cheese& cheese = map.obtain(); + cheese.name = "Cheese"; + + Chowdah& chowdah = map.obtain(); + chowdah.name = "Chowdah"; + } // refs go out of scope + + { + // verify each instance + Chalk& chalk = map.obtain(); + ensure_equals(chalk.name, "Chalk"); + + Cheese& cheese = map.obtain(); + ensure_equals(cheese.name, "Cheese"); + + Chowdah& chowdah = map.obtain(); + ensure_equals(chowdah.name, "Chowdah"); + } + } // destroy map + + // Chalk, Cheese and Chowdah should have been created in specific order + ensure_equals(clog, "aeo"); + + // We don't care what order they're destroyed in, as long as each is + // appropriately destroyed. + std::set dtorset; + for (const char* cp = "aeo"; *cp; ++cp) + dtorset.insert(std::string(1, *cp)); + ensure_equals(dlog, dtorset); + } +} // namespace tut diff --git a/indra/llcommon/tests/llpounceable_test.cpp b/indra/llcommon/tests/llpounceable_test.cpp new file mode 100644 index 0000000000..2f4915ce11 --- /dev/null +++ b/indra/llcommon/tests/llpounceable_test.cpp @@ -0,0 +1,230 @@ +/** + * @file llpounceable_test.cpp + * @author Nat Goodspeed + * @date 2015-05-22 + * @brief Test for llpounceable. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Copyright (c) 2015, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llpounceable.h" +// STL headers +// std headers +// external library headers +#include +// other Linden headers +#include "../test/lltut.h" + +/*----------------------------- string testing -----------------------------*/ +void append(std::string* dest, const std::string& src) +{ + dest->append(src); +} + +/*-------------------------- Data-struct testing ---------------------------*/ +struct Data +{ + Data(const std::string& data): + mData(data) + {} + const std::string mData; +}; + +void setter(Data** dest, Data* ptr) +{ + *dest = ptr; +} + +static Data* static_check = 0; + +// Set up an extern pointer to an LLPounceableStatic so the linker will fill +// in the forward reference from below, before runtime. +extern LLPounceable gForward; + +struct EnqueueCall +{ + EnqueueCall() + { + // Intentionally use a forward reference to an LLPounceableStatic that + // we believe is NOT YET CONSTRUCTED. This models the scenario in + // which a constructor in another translation unit runs before + // constructors in this one. We very specifically want callWhenReady() + // to work even in that case: we need the LLPounceableQueueImpl to be + // initialized even if the LLPounceable itself is not. + gForward.callWhenReady(boost::bind(setter, &static_check, _1)); + } +} nqcall; +// When this declaration is processed, we should enqueue the +// setter(&static_check, _1) call for when gForward is set non-NULL. Needless +// to remark, we want this call not to crash. + +// Now declare gForward. Its constructor should not run until after nqcall's. +LLPounceable gForward; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llpounceable_data + { + }; + typedef test_group llpounceable_group; + typedef llpounceable_group::object object; + llpounceable_group llpounceablegrp("llpounceable"); + + template<> template<> + void object::test<1>() + { + set_test_name("LLPounceableStatic out-of-order test"); + // LLPounceable::callWhenReady() must work even + // before LLPounceable's constructor runs. That's the whole point of + // implementing it with an LLSingleton queue. This models (say) + // LLPounceableStatic. + ensure("static_check should still be null", ! static_check); + Data myData("test<1>"); + gForward = &myData; // should run setter + ensure_equals("static_check should be &myData", static_check, &myData); + } + + template<> template<> + void object::test<2>() + { + set_test_name("LLPounceableQueue different queues"); + // We expect that LLPounceable should have + // different queues because that specialization stores the queue + // directly in the LLPounceable instance. + Data *aptr = 0, *bptr = 0; + LLPounceable a, b; + a.callWhenReady(boost::bind(setter, &aptr, _1)); + b.callWhenReady(boost::bind(setter, &bptr, _1)); + ensure("aptr should be null", ! aptr); + ensure("bptr should be null", ! bptr); + Data adata("a"), bdata("b"); + a = &adata; + ensure_equals("aptr should be &adata", aptr, &adata); + // but we haven't yet set b + ensure("bptr should still be null", !bptr); + b = &bdata; + ensure_equals("bptr should be &bdata", bptr, &bdata); + } + + template<> template<> + void object::test<3>() + { + set_test_name("LLPounceableStatic different queues"); + // LLPounceable should also have a distinct + // queue for each instance, but that engages an additional map lookup + // because there's only one LLSingleton for each T. + Data *aptr = 0, *bptr = 0; + LLPounceable a, b; + a.callWhenReady(boost::bind(setter, &aptr, _1)); + b.callWhenReady(boost::bind(setter, &bptr, _1)); + ensure("aptr should be null", ! aptr); + ensure("bptr should be null", ! bptr); + Data adata("a"), bdata("b"); + a = &adata; + ensure_equals("aptr should be &adata", aptr, &adata); + // but we haven't yet set b + ensure("bptr should still be null", !bptr); + b = &bdata; + ensure_equals("bptr should be &bdata", bptr, &bdata); + } + + template<> template<> + void object::test<4>() + { + set_test_name("LLPounceable looks like T"); + // We want LLPounceable to be drop-in replaceable for a plain + // T for read constructs. In particular, it should behave like a dumb + // pointer -- and with zero abstraction cost for such usage. + Data* aptr = 0; + Data a("a"); + // should be able to initialize a pounceable (when its constructor + // runs) + LLPounceable pounceable(&a); + // should be able to pass LLPounceable to function accepting T + setter(&aptr, pounceable); + ensure_equals("aptr should be &a", aptr, &a); + // should be able to dereference with * + ensure_equals("deref with *", (*pounceable).mData, "a"); + // should be able to dereference with -> + ensure_equals("deref with ->", pounceable->mData, "a"); + // bool operations + ensure("test with operator bool()", pounceable); + ensure("test with operator !()", ! (! pounceable)); + } + + template<> template<> + void object::test<5>() + { + set_test_name("Multiple callWhenReady() queue items"); + Data *p1 = 0, *p2 = 0, *p3 = 0; + Data a("a"); + LLPounceable pounceable; + // queue up a couple setter() calls for later + pounceable.callWhenReady(boost::bind(setter, &p1, _1)); + pounceable.callWhenReady(boost::bind(setter, &p2, _1)); + // should still be pending + ensure("p1 should be null", !p1); + ensure("p2 should be null", !p2); + ensure("p3 should be null", !p3); + pounceable = 0; + // assigning a new empty value shouldn't flush the queue + ensure("p1 should still be null", !p1); + ensure("p2 should still be null", !p2); + ensure("p3 should still be null", !p3); + // using whichever syntax + pounceable.reset(0); + // try to make ensure messages distinct... tough to pin down which + // ensure() failed if multiple ensure() calls in the same test have + // the same message! + ensure("p1 should again be null", !p1); + ensure("p2 should again be null", !p2); + ensure("p3 should again be null", !p3); + pounceable.reset(&a); // should flush queue + ensure_equals("p1 should be &a", p1, &a); + ensure_equals("p2 should be &a", p2, &a); + ensure("p3 still not set", !p3); + // immediate call + pounceable.callWhenReady(boost::bind(setter, &p3, _1)); + ensure_equals("p3 should be &a", p3, &a); + } + + template<> template<> + void object::test<6>() + { + set_test_name("queue order"); + std::string data; + LLPounceable pounceable; + pounceable.callWhenReady(boost::bind(append, _1, "a")); + pounceable.callWhenReady(boost::bind(append, _1, "b")); + pounceable.callWhenReady(boost::bind(append, _1, "c")); + pounceable = &data; + ensure_equals("callWhenReady() must preserve chronological order", + data, "abc"); + + std::string data2; + pounceable = NULL; + pounceable.callWhenReady(boost::bind(append, _1, "d")); + pounceable.callWhenReady(boost::bind(append, _1, "e")); + pounceable.callWhenReady(boost::bind(append, _1, "f")); + pounceable = &data2; + ensure_equals("LLPounceable must reset queue when fired", + data2, "def"); + } + + template<> template<> + void object::test<7>() + { + set_test_name("compile-fail test, uncomment to check"); + // The following declaration should fail: only LLPounceableQueue and + // LLPounceableStatic should work as tags. +// LLPounceable pounceable; + } +} // namespace tut diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp index 385289aefe..56886bc73f 100644 --- a/indra/llcommon/tests/llsingleton_test.cpp +++ b/indra/llcommon/tests/llsingleton_test.cpp @@ -30,47 +30,172 @@ #include "llsingleton.h" #include "../test/lltut.h" + +// Capture execution sequence by appending to log string. +std::string sLog; + +#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; \ + \ + void initSingleton(); \ + void cleanupSingleton(); \ +}; \ + \ +CLS::dep_flag CLS::sDepFlag = DEP_NONE + +DECLARE_CLASS(A); +DECLARE_CLASS(B); + +#define DEFINE_MEMBERS(CLS, OTHER) \ +CLS::CLS() \ +{ \ + sLog.append(#CLS); \ + if (sDepFlag == DEP_CTOR) \ + { \ + (void)OTHER::instance(); \ + } \ +} \ + \ +void CLS::initSingleton() \ +{ \ + sLog.append("i" #CLS); \ + if (sDepFlag == DEP_INIT) \ + { \ + (void)OTHER::instance(); \ + } \ +} \ + \ +void CLS::cleanupSingleton() \ +{ \ + sLog.append("x" #CLS); \ +} \ + \ +CLS::~CLS() \ +{ \ + sLog.append("~" #CLS); \ +} + +DEFINE_MEMBERS(A, B) +DEFINE_MEMBERS(B, A) + namespace tut { - struct singleton - { - // We need a class created with the LLSingleton template to test with. - class LLSingletonTest: public LLSingleton - { + struct singleton + { + // We need a class created with the LLSingleton template to test with. + class LLSingletonTest: public LLSingleton + { + LLSINGLETON_EMPTY_CTOR(LLSingletonTest); + }; + }; - }; - }; + typedef test_group singleton_t; + typedef singleton_t::object singleton_object_t; + tut::singleton_t tut_singleton("LLSingleton"); - typedef test_group singleton_t; - typedef singleton_t::object singleton_object_t; - tut::singleton_t tut_singleton("LLSingleton"); + template<> template<> + void singleton_object_t::test<1>() + { - template<> template<> - void singleton_object_t::test<1>() - { + } + template<> template<> + void singleton_object_t::test<2>() + { + LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); + ensure(singleton_test); + } - } - template<> template<> - void singleton_object_t::test<2>() - { - LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); - ensure(singleton_test); - } - template<> template<> - void singleton_object_t::test<3>() - { - //Construct the instance - LLSingletonTest::getInstance(); - ensure(LLSingletonTest::instanceExists()); + template<> template<> + void singleton_object_t::test<3>() + { + //Construct the instance + LLSingletonTest::getInstance(); + ensure(LLSingletonTest::instanceExists()); - //Delete the instance - LLSingletonTest::deleteSingleton(); - ensure(LLSingletonTest::destroyed()); - ensure(!LLSingletonTest::instanceExists()); + //Delete the instance + LLSingletonTest::deleteSingleton(); + ensure(!LLSingletonTest::instanceExists()); - //Construct it again. - LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); - ensure(singleton_test); - ensure(LLSingletonTest::instanceExists()); - } + //Construct it again. + LLSingletonTest* singleton_test = LLSingletonTest::getInstance(); + ensure(singleton_test); + ensure(LLSingletonTest::instanceExists()); + } + +#define TESTS(CLS, OTHER, N0, N1, N2, N3) \ + template<> template<> \ + void singleton_object_t::test() \ + { \ + set_test_name("just " #CLS); \ + CLS::sDepFlag = CLS::DEP_NONE; \ + OTHER::sDepFlag = OTHER::DEP_NONE; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS "i" #CLS); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS "i" #CLS "x" #CLS); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS "i" #CLS "x" #CLS "~" #CLS); \ + } \ + \ + template<> template<> \ + void singleton_object_t::test() \ + { \ + set_test_name(#CLS " ctor depends " #OTHER); \ + CLS::sDepFlag = CLS::DEP_CTOR; \ + OTHER::sDepFlag = OTHER::DEP_NONE; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \ + } \ + \ + template<> template<> \ + void singleton_object_t::test() \ + { \ + set_test_name(#CLS " init depends " #OTHER); \ + CLS::sDepFlag = CLS::DEP_INIT; \ + OTHER::sDepFlag = OTHER::DEP_NONE; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \ + } \ + \ + template<> template<> \ + void singleton_object_t::test() \ + { \ + set_test_name(#CLS " circular init"); \ + CLS::sDepFlag = CLS::DEP_INIT; \ + OTHER::sDepFlag = OTHER::DEP_CTOR; \ + sLog.clear(); \ + \ + (void)CLS::instance(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER); \ + LLSingletonBase::cleanupAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \ + LLSingletonBase::deleteAll(); \ + ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \ + } + + TESTS(A, B, 4, 5, 6, 7) + TESTS(B, A, 8, 9, 10, 11) } diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 1b5491e505..29ef0b3e90 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -97,6 +97,7 @@ target_link_libraries( ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${BOOST_THREAD_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) # tests @@ -133,8 +134,8 @@ if (LL_TESTS) ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_SYSTEM_LIBRARY} ${BOOST_THREAD_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) # If http_proxy is in the current environment (e.g. to fetch s3-proxy @@ -203,8 +204,8 @@ endif (DARWIN) ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_SYSTEM_LIBRARY} ${BOOST_THREAD_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) add_executable(http_texture_load diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp old mode 100644 new mode 100755 index bef762f5ce..a310fc0508 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -46,6 +46,7 @@ #include "test_httprequestqueue.hpp" #include "llproxy.h" +#include "llcleanup.h" unsigned long ssl_thread_id_callback(void); void ssl_locking_callback(int mode, int type, const char * file, int line); @@ -101,7 +102,7 @@ void init_curl() void term_curl() { - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); CRYPTO_set_locking_callback(NULL); for (int i(0); i < ssl_mutex_count; ++i) diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 463e55dd7e..6cd7960ecd 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -729,7 +729,7 @@ void HttpRequestTestObjectType::test<7>() #if 0 // defined(WIN32) // Can't do this on any platform anymore, the LL logging system holds // on to memory and produces what looks like memory leaks... - + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif @@ -1459,21 +1459,21 @@ void HttpRequestTestObjectType::test<14>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; HttpRequest * req = NULL; HttpOptions::ptr_t opts; - + try { - // Get singletons created + // Get singletons created HttpRequest::createService(); - + // Start threading early so that thread memory is invariant // over the test. HttpRequest::startThread(); @@ -1482,10 +1482,10 @@ void HttpRequestTestObjectType::test<14>() req = new HttpRequest(); ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); - opts = HttpOptions::ptr_t(new HttpOptions); - opts->setRetries(0); // Don't retry + opts = HttpOptions::ptr_t(new HttpOptions); + opts->setRetries(0); // Don't retry opts->setTimeout(2); - + // Issue a GET that sleeps mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, @@ -1494,8 +1494,8 @@ void HttpRequestTestObjectType::test<14>() 0, 0, opts, - HttpHeaders::ptr_t(), - handlerp); + HttpHeaders::ptr_t(), + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1513,7 +1513,7 @@ void HttpRequestTestObjectType::test<14>() mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - + // Run the notification pump again count = 0; limit = LOOP_COUNT_LONG; @@ -1535,30 +1535,29 @@ void HttpRequestTestObjectType::test<14>() ensure("Thread actually stopped running", HttpService::isStopped()); // release options - opts.reset(); - + opts.reset(); + // release the request object delete req; req = NULL; // Shut down service HttpRequest::destroyService(); - + ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) - // Can only do this memory test on Windows. On other platforms, - // the LL logging system holds on to memory and produces what looks - // like memory leaks... - - // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif } catch (...) { stop_thread(req); - opts.reset(); + opts.reset(); delete req; HttpRequest::destroyService(); throw; @@ -3065,12 +3064,11 @@ void HttpRequestTestObjectType::test<22>() // Shut down service HttpRequest::destroyService(); - -#if defined(WIN32) - // Can only do this memory test on Windows. On other platforms, - // the LL logging system holds on to memory and produces what looks - // like memory leaks... - + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif @@ -3195,12 +3193,11 @@ void HttpRequestTestObjectType::test<23>() // Shut down service HttpRequest::destroyService(); - -#if defined(WIN32) - // Can only do this memory test on Windows. On other platforms, - // the LL logging system holds on to memory and produces what looks - // like memory leaks... - + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); #endif diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index b585d8eed9..a7ca067e12 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -45,6 +45,7 @@ #include "llhttpsdhandler.h" #include "httpcommon.h" #include "httpresponse.h" +#include "llcleanup.h" #include #include @@ -779,7 +780,7 @@ void LLCrashLogger::commonCleanup() { term_curl(); LLError::logToFile(""); //close crashreport.log - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); } void LLCrashLogger::init_curl() 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 47fcf688a2..cdfde171c1 100644 --- a/indra/llinventory/lleconomy.h +++ b/indra/llinventory/lleconomy.h @@ -42,18 +42,11 @@ public: virtual void onEconomyDataChange() = 0; }; -class LLGlobalEconomy +class LLBaseEconomy { public: - LLGlobalEconomy(); - virtual ~LLGlobalEconomy(); - - // This class defines its singleton internally as a typedef instead of inheriting from - // LLSingleton like most others because the LLRegionEconomy sub-class might also - // become a singleton and this pattern will more easily disambiguate them. - typedef LLSingleton Singleton; - - void initSingleton() { } + LLBaseEconomy(); + virtual ~LLBaseEconomy(); virtual void print(); @@ -61,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; @@ -108,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 f10e9b916f..401825e460 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -64,8 +64,7 @@ struct InventoryEntry : public LLDictionaryEntry class LLInventoryDictionary : public LLSingleton, public LLDictionary { -public: - LLInventoryDictionary(); + LLSINGLETON(LLInventoryDictionary); }; LLInventoryDictionary::LLInventoryDictionary() diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index a0653dd373..6b82a3b5c4 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -254,6 +254,11 @@ inline int round_int(double x) } #endif // BOGUS_ROUND +inline F64 ll_round(const F64 val) +{ + return F64(floor(val + 0.5f)); +} + inline F32 ll_round( F32 val, F32 nearest ) { return F32(floor(val * (1.0f / nearest) + 0.5f)) * nearest; 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/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp index 257a13f277..8e2ed890e7 100644 --- a/indra/llmessage/llxfer_file.cpp +++ b/indra/llmessage/llxfer_file.cpp @@ -98,12 +98,12 @@ void LLXfer_File::cleanup () mFp = NULL; } - LLFile::remove(mTempFilename); + LLFile::remove(mTempFilename, ENOENT); if (mDeleteLocalOnCompletion) { LL_DEBUGS() << "Removing file: " << mLocalFilename << LL_ENDL; - LLFile::remove(mLocalFilename); + LLFile::remove(mLocalFilename, ENOENT); } else { @@ -321,7 +321,7 @@ S32 LLXfer_File::processEOF() mCallbackResult = flushval; } - LLFile::remove(mLocalFilename); + LLFile::remove(mLocalFilename, ENOENT); if (!mCallbackResult) { diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 272dbbc785..2ceb64ce8f 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -444,7 +444,7 @@ U64 LLXferManager::requestFile(const std::string& local_filename, && (remote_filename.substr(remote_filename.length()-4) == ".tmp") && gDirUtilp->fileExists(local_filename)) { - LLFile::remove(local_filename); + LLFile::remove(local_filename, ENOENT); } xfer_id = getNextID(); ((LLXfer_File *)xferp)->initializeRequest( diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 9068026bf0..87ae43e268 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -76,6 +76,7 @@ #include "v4math.h" #include "lltransfertargetvfile.h" #include "llcorehttputil.h" +#include "llpounceable.h" #include "nd/ndexceptions.h" // For ndxran @@ -1735,7 +1736,9 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg) return s; } -LLMessageSystem *gMessageSystem = NULL; +// LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.) +// callback registrations for when gMessageSystem is first assigned +LLPounceable gMessageSystem; // update appropriate ping info void process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/) @@ -2652,7 +2655,7 @@ void end_messaging_system(bool print_summary) LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL; } - delete gMessageSystem; + delete static_cast(gMessageSystem); gMessageSystem = NULL; } } diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 5ed66439e5..4132d4edfd 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -60,6 +60,7 @@ #include "llstoredmessage.h" #include "boost/function.hpp" +#include "llpounceable.h" const U32 MESSAGE_MAX_STRINGS_LENGTH = 64; const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; @@ -68,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; @@ -838,7 +839,7 @@ private: // external hook into messaging system -extern LLMessageSystem *gMessageSystem; +extern LLPounceable gMessageSystem; // Must specific overall system version, which is used to determine // if a patch is available in the message template checksum verification. diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index a32bfa59ce..9356a14f1f 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -42,6 +42,7 @@ #include "lliosocket.h" #include "stringize.h" +#include "llcleanup.h" namespace tut { @@ -66,7 +67,7 @@ namespace tut ~HTTPClientTestData() { delete mClientPump; - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); apr_pool_destroy(mPool); } diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp index 3b04530c1a..e20f61b73f 100644 --- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -31,11 +31,12 @@ #include "llhost.h" #include "message.h" #include "llsd.h" +#include "llpounceable.h" #include "llhost.cpp" // Needed for copy operator #include "net.cpp" // Needed by LLHost. -LLMessageSystem * gMessageSystem = NULL; +LLPounceable gMessageSystem; // sensor test doubles bool gClearRecvWasCalled = false; diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp index 55748ad27e..41f982a7e2 100644 --- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -33,8 +33,9 @@ #include "message.h" #include "llmessageconfig.h" #include "llhttpnode_stub.cpp" +#include "llpounceable.h" -LLMessageSystem* gMessageSystem = NULL; +LLPounceable gMessageSystem; LLMessageConfig::SenderTrust LLMessageConfig::getSenderTrustedness(const std::string& msg_name) diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h index 5eb739393f..5986524342 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -44,7 +44,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) @@ -69,6 +69,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/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 360098c547..afeaaf4f12 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -267,7 +267,14 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) } else { - LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + if (texture) + { + LL_DEBUGS() << "NULL LLTexUnit::bind GL image" << LL_ENDL; + } + else + { + LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + } return false; } } @@ -286,7 +293,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) if(!texture) { - LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL; + LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL; return false; } 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 2bf9c9fdcc..251f5d2c42 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -189,6 +189,9 @@ public: class LLCommandManager : public LLSingleton { + LLSINGLETON(LLCommandManager); + ~LLCommandManager(); + public: struct Params : public LLInitParam::Block { @@ -200,9 +203,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/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index a709469829..15a9c8bb0a 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -114,6 +114,81 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null* return true; } +bool LLFlatListView::addItemPairs(pairs_list_t panel_list, bool rearrange /*= true*/) +{ + if (!mItemComparator) + { + LL_WARNS_ONCE() << "No comparator specified for inserting FlatListView items." << LL_ENDL; + return false; + } + if (panel_list.size() == 0) + { + return false; + } + + // presort list so that it will be easier to sort elements into mItemPairs + panel_list.sort(ComparatorAdaptor(*mItemComparator)); + + pairs_const_iterator_t new_pair_it = panel_list.begin(); + item_pair_t* new_pair = *new_pair_it; + pairs_iterator_t pair_it = mItemPairs.begin(); + item_pair_t* item_pair = *pair_it; + + // sort panel_list into mItemPars + while (new_pair_it != panel_list.end() && pair_it != mItemPairs.end()) + { + if (!new_pair->first || new_pair->first->getParent() == mItemsPanel) + { + // iterator already used or we are reusing existing panel + new_pair_it++; + new_pair = *new_pair_it; + } + else if (mItemComparator->compare(new_pair->first, item_pair->first)) + { + LLPanel* panel = new_pair->first; + + mItemPairs.insert(pair_it, new_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + else + { + pair_it++; + item_pair = *pair_it; + } + } + + // Add what is left of panel_list into the end of mItemPairs. + for (; new_pair_it != panel_list.end(); ++new_pair_it) + { + item_pair_t* item_pair = *new_pair_it; + LLPanel *panel = item_pair->first; + if (panel && panel->getParent() != mItemsPanel) + { + mItemPairs.push_back(item_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, item_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, item_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + } + + if (rearrange) + { + rearrangeItems(); + notifyParentItemsRectChanged(); + } + return true; +} + bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/) { @@ -1301,6 +1376,28 @@ void LLFlatListViewEx::setFilterSubString(const std::string& filter_str) } } +void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action) +{ + if (!item) return; + + // 0 signifies that filter is matched, + // i.e. we don't hide items that don't support 'match_filter' action, separators etc. + if (0 == item->notify(action)) + { + mHasMatchedItems = true; + item->setVisible(true); + } + else + { + // TODO: implement (re)storing of current selection. + if (!mForceShowingUnmatchedItems) + { + selectItem(item, false); + } + item->setVisible(mForceShowingUnmatchedItems); + } +} + void LLFlatListViewEx::filterItems() { typedef std::vector item_panel_list_t; @@ -1321,22 +1418,7 @@ void LLFlatListViewEx::filterItems() iter != iter_end; ++iter) { LLPanel* pItem = (*iter); - // 0 signifies that filter is matched, - // i.e. we don't hide items that don't support 'match_filter' action, separators etc. - if (0 == pItem->notify(action)) - { - mHasMatchedItems = true; - pItem->setVisible(true); - } - else - { - // TODO: implement (re)storing of current selection. - if(!mForceShowingUnmatchedItems) - { - selectItem(pItem, false); - } - pItem->setVisible(mForceShowingUnmatchedItems); - } + updateItemVisibility(pItem, action); } sort(); diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 39286160cf..c2ba8f2f02 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -359,6 +359,8 @@ protected: virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange); + bool addItemPairs(pairs_list_t panel_list, bool rearrange = true); + /** * Notify parent about changed size of internal controls with "size_changes" action * @@ -494,6 +496,7 @@ public: * Sets up new filter string and filters the list. */ void setFilterSubString(const std::string& filter_str); + std::string getFilterSubString() { return mFilterSubString; } /** * Filters the list, rearranges and notifies parent about shape changes. @@ -517,6 +520,14 @@ protected: */ void updateNoItemsMessage(const std::string& filter_string); + /** + * Applies visibility acording to action and LLFlatListView settings. + * + * @param item - item we are changing + * @param item - action - parameters to determin visibility from + */ + void updateItemVisibility(LLPanel* item, const LLSD &action); + private: std::string mNoFilteredItemsMsg; std::string mNoItemsMsg; 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 0f1929d29c..87a9dd9921 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 4b8b16beaf..d5a356ba09 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -351,7 +351,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 923249935f..7ec574caeb 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -890,9 +890,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 @@ -972,8 +972,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 ed6e1b6580..175808be00 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 6395cb0f9b..96224830f2 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 4ab80195ea..acac589e43 100644 --- a/indra/llui/llspellcheck.h +++ b/indra/llui/llspellcheck.h @@ -29,16 +29,15 @@ #include "llsingleton.h" #include "llui.h" +#include "llinitdestroyclass.h" #include 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/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 85bf3242df..194262d405 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -158,10 +158,7 @@ F32 clamp_precision(F32 value, S32 decimal_precision) for (S32 i = 0; i < decimal_precision; i++) clamped_value *= 10.0; - // FIRE-5630: Round with additional precision because of small numbers - //clamped_value = ll_round((F32)clamped_value); - clamped_value = floor(clamped_value + 0.5); - // + clamped_value = ll_round(clamped_value); for (S32 i = 0; i < decimal_precision; i++) clamped_value /= 10.0; 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/llui.cpp b/indra/llui/llui.cpp index a4e63928e7..5e0d7c47b9 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -60,6 +60,7 @@ #include "llflyoutbutton.h" #include "llsearcheditor.h" #include "lltoolbar.h" +#include "llcleanup.h" // for XUIParse #include "llquaternion.h" @@ -235,7 +236,7 @@ void LLUI::initClass(const settings_map_t& settings, void LLUI::cleanupClass() { - LLRender2D::cleanupClass(); + SUBSYSTEM_CLEANUP(LLRender2D); } void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 096e805e6a..cfbe1214bd 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -352,95 +352,6 @@ private: // Moved LLLocalClipRect to lllocalcliprect.h -class LLCallbackRegistry -{ -public: - typedef boost::signals2::signal callback_signal_t; - - void registerCallback(const callback_signal_t::slot_type& slot) - { - mCallbacks.connect(slot); - } - - void fireCallbacks() - { - mCallbacks(); - } - -private: - callback_signal_t mCallbacks; -}; - -class LLInitClassList : - public LLCallbackRegistry, - public LLSingleton -{ - friend class LLSingleton; -private: - LLInitClassList() {} -}; - -class LLDestroyClassList : - public LLCallbackRegistry, - public LLSingleton -{ - friend class LLSingleton; -private: - LLDestroyClassList() {} -}; - -template -class LLRegisterWith -{ -public: - LLRegisterWith(boost::function func) - { - T::instance().registerCallback(func); - } - - // this avoids a MSVC bug where non-referenced static members are "optimized" away - // even if their constructors have side effects - S32 reference() - { - S32 dummy; - dummy = 0; - return dummy; - } -}; - -template -class LLInitClass -{ -public: - LLInitClass() { sRegister.reference(); } - - static LLRegisterWith sRegister; -private: - - static void initClass() - { - LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template -class LLDestroyClass -{ -public: - LLDestroyClass() { sRegister.reference(); } - - static LLRegisterWith sRegister; -private: - - static void destroyClass() - { - LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template LLRegisterWith LLInitClass::sRegister(&T::initClass); -template LLRegisterWith LLDestroyClass::sRegister(&T::destroyClass); - // useful parameter blocks struct TimeIntervalParam : public LLInitParam::ChoiceBlock { diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 147dab8a54..51c7390227 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 diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index deab7fc6ee..8671d86cee 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -277,18 +277,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..03d946f1b7 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -33,6 +33,8 @@ #include "llxuiparser.h" #include "llstl.h" #include "lldir.h" +#include "llsingleton.h" +#include "llheteromap.h" class LLView; @@ -57,22 +59,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 +89,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 > + class 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()); - - } - + ParamDefaults(); const PARAM_BLOCK& get() { return mPrototype; } private: @@ -118,9 +106,10 @@ private: // base case for recursion, there are NO base classes of LLInitParam::BaseBlock template - class ParamDefaults : public LLSingleton > + class ParamDefaults { public: + ParamDefaults(); const LLInitParam::BaseBlock& get() { return mBaseBlock; } private: LLInitParam::BaseBlock mBaseBlock; @@ -132,7 +121,7 @@ public: template static const typename T::Params& getDefaultParams() { - return ParamDefaults::instance().get(); + return instance().mParamDefaultsMap.obtain< ParamDefaults >().get(); } // Does what you want for LLFloaters and LLPanels @@ -147,7 +136,8 @@ public: template static T* create(typename T::Params& params, LLView* parent = NULL) { - params.fillFrom(ParamDefaults::instance().get()); + params.fillFrom(instance().mParamDefaultsMap.obtain< + ParamDefaults >().get()); T* widget = createWidgetImpl(params, parent); if (widget) @@ -295,8 +285,40 @@ private: class LLPanel* mDummyPanel; std::vector mFileNames; + + // store ParamDefaults specializations + // Each ParamDefaults specialization used to be an LLSingleton in its own + // right. But the 2016 changes to the LLSingleton mechanism, making + // LLSingleton instances polymorphic, are incompatible with current + // LLInitParam::BaseBlock functionality. (Thanks NickyD for spotting + // that!) Moreover, instances of the private nested ParamDefaults template + // aren't global resources -- which is what LLSingleton is designed for. + // This is simply a cache looked up by type. Its lifespan is tied to + // LLUICtrlFactory. Use LLHeteroMap for this cache. + LLHeteroMap mParamDefaultsMap; }; +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( + LLUICtrlFactory::instance().mParamDefaultsMap.obtain< + ParamDefaults >().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 43132d17d7..9ea7cfc981 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 88ebda6aec..51910d01b6 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1973,6 +1973,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())); @@ -1996,6 +1997,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..eb0eac8194 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 { @@ -60,7 +64,7 @@ public: void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } - + /*virtual*/ std::string getCurrentFileName() { return LLStringUtil::null; } LLXSDWriter(); ~LLXSDWriter(); @@ -98,6 +102,7 @@ public: typedef LLInitParam::Parser::name_stack_t name_stack_t; /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); @@ -200,6 +205,7 @@ public: virtual ~LLSimpleXUIParser(); /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp old mode 100644 new mode 100755 index ec6fcf4d75..36aa316696 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -31,6 +31,7 @@ #include "llcachename.h" #include "lluuid.h" #include "message.h" +#include "llpounceable.h" #include @@ -174,7 +175,7 @@ LLFontGL* LLFontGL::getFontDefault() char const* const _PREHASH_AgentData = (char *)"AgentData"; char const* const _PREHASH_AgentID = (char *)"AgentID"; -LLMessageSystem* gMessageSystem = NULL; +LLPounceable gMessageSystem; // // Stub implementation for LLMessageSystem diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp index 3b52941e96..6953ad3ab8 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(); - F32 mVolume; F32 mPan; bool mSystemIsVistaOrHigher; diff --git a/indra/newview/NACLantispam.h b/indra/newview/NACLantispam.h index 48657e92e6..870bcf7e8a 100644 --- a/indra/newview/NACLantispam.h +++ b/indra/newview/NACLantispam.h @@ -91,7 +91,8 @@ private: class NACLAntiSpamRegistry : public LLSingleton { - friend class LLSingleton; + LLSINGLETON(NACLAntiSpamRegistry); + ~NACLAntiSpamRegistry(); public: void setGlobalQueue(bool value); @@ -117,9 +118,6 @@ public: void processObjectPropertiesFamily(LLMessageSystem* msg); private: - NACLAntiSpamRegistry(); - ~NACLAntiSpamRegistry(); - const char* getQueueName(EAntispamQueue queue); void blockGlobalEntry(const LLUUID& source); diff --git a/indra/newview/animationexplorer.h b/indra/newview/animationexplorer.h index d0891f587b..ddda69002f 100644 --- a/indra/newview/animationexplorer.h +++ b/indra/newview/animationexplorer.h @@ -43,24 +43,21 @@ class AnimationExplorer; class RecentAnimationList : public LLSingleton { - friend class LLSingleton; + LLSINGLETON(RecentAnimationList); + ~RecentAnimationList(); - private: - RecentAnimationList(); - ~RecentAnimationList(); +public: + struct AnimationEntry + { + LLUUID animationID; // asset ID of the animation + LLUUID playedBy; // object/agent who played this animation + F64 time; // time in seconds since viewer start when the animation started + }; - public: - struct AnimationEntry - { - LLUUID animationID; // asset ID of the animation - LLUUID playedBy; // object/agent who played this animation - F64 time; // time in seconds since viewer start when the animation started - }; + std::deque mAnimationList; - std::deque mAnimationList; - - void addAnimation(const LLUUID& id, const LLUUID& playedBy); // called in llviewermessage.cpp - void requestList(AnimationExplorer* explorer); // request animation list + void addAnimation(const LLUUID& id, const LLUUID& playedBy); // called in llviewermessage.cpp + void requestList(AnimationExplorer* explorer); // request animation list }; // -------------------------------------------------------------------------- diff --git a/indra/newview/aoengine.h b/indra/newview/aoengine.h index 95699ba696..21f58862e2 100644 --- a/indra/newview/aoengine.h +++ b/indra/newview/aoengine.h @@ -87,11 +87,8 @@ class LLVFS; class AOEngine : public LLSingleton { - friend class LLSingleton; - - private: - AOEngine(); - ~AOEngine(); + LLSINGLETON(AOEngine); + ~AOEngine(); public: enum eCycleMode diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index d745b3c380..14808863cb 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -285,6 +285,16 @@ is_running_function="Floater.IsOpen" is_running_parameters="camera" /> + Value 0 + MuteListLimit + + Comment + Maximum number of entries in the mute list + Persist + 1 + Type + S32 + Value + 1000 + NearMeRange Comment diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 9e95b889c5..bebc681b1e 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -488,6 +488,17 @@ Value 0 + PreviousScreenshotForReport + + Comment + Use Previous Screenshot for Abuse report + Persist + 1 + Type + Boolean + Value + 0 + TranslatingEnabled Comment @@ -598,7 +610,6 @@ Value 1 - DebugLookAt diff --git a/indra/newview/dialogstack.cpp b/indra/newview/dialogstack.cpp index e646958cdc..38acbb402a 100644 --- a/indra/newview/dialogstack.cpp +++ b/indra/newview/dialogstack.cpp @@ -28,15 +28,6 @@ #include "llviewercontrol.h" -DialogStack::DialogStack() : - LLSingleton() -{ -} - -DialogStack::~DialogStack() -{ -} - void DialogStack::update() { // show dialog stack browse icon when more than one dialog is on the screen diff --git a/indra/newview/dialogstack.h b/indra/newview/dialogstack.h index 3e52c90557..df08828d49 100644 --- a/indra/newview/dialogstack.h +++ b/indra/newview/dialogstack.h @@ -30,11 +30,8 @@ class DialogStack : public LLSingleton { -friend class LLSingleton; - -private: - DialogStack(); - ~DialogStack(); + LLSINGLETON_EMPTY_CTOR(DialogStack); + ~DialogStack() {} protected: void update(); diff --git a/indra/newview/exogroupmutelist.h b/indra/newview/exogroupmutelist.h index 548cae6cd6..efd2b4b79f 100644 --- a/indra/newview/exogroupmutelist.h +++ b/indra/newview/exogroupmutelist.h @@ -24,8 +24,9 @@ class exoGroupMuteList : public LLSingleton { + LLSINGLETON(exoGroupMuteList); + public: - exoGroupMuteList(); bool isMuted(const LLUUID &group) const; void add(const LLUUID &group); void remove(const LLUUID &group); diff --git a/indra/newview/exopostprocess.h b/indra/newview/exopostprocess.h index 3e6ad3ab27..232d299a9d 100644 --- a/indra/newview/exopostprocess.h +++ b/indra/newview/exopostprocess.h @@ -36,12 +36,13 @@ public: class exoPostProcess : public LLSingleton { - friend class LLSingleton; + LLSINGLETON(exoPostProcess); + ~exoPostProcess(); + private: static exoPostProcess *postProcess; - exoPostProcess(); + public: - ~exoPostProcess(); enum ExodusRenderPostType { //EXODUS_RENDER_GAMMA_POST = 1, diff --git a/indra/newview/fsareasearch.h b/indra/newview/fsareasearch.h index 0f0da7f8e3..d308f26ab6 100644 --- a/indra/newview/fsareasearch.h +++ b/indra/newview/fsareasearch.h @@ -29,7 +29,6 @@ #define FS_AREASEARCH_H #include "llfloater.h" -#include "llsingleton.h" #include "llframetimer.h" #include "llsaleinfo.h" #include "llcategory.h" @@ -102,7 +101,7 @@ struct FSObjectProperties // Main class for area search // holds the search engine and main floater // -------------------------------------------------------------------- -class FSAreaSearch : public LLSingleton, public LLFloater +class FSAreaSearch : public LLFloater { LOG_CLASS(FSAreaSearch); public: diff --git a/indra/newview/fsassetblacklist.h b/indra/newview/fsassetblacklist.h index a6b4cf87b1..1263f0c9b9 100644 --- a/indra/newview/fsassetblacklist.h +++ b/indra/newview/fsassetblacklist.h @@ -41,6 +41,8 @@ typedef boost::unordered_map blacklist_data_t; class FSAssetBlacklist : public LLSingleton { + LLSINGLETON_EMPTY_CTOR(FSAssetBlacklist); + public: void init(); bool isBlacklisted(const LLUUID& id, LLAssetType::EType type); diff --git a/indra/newview/fsavatarrenderpersistence.h b/indra/newview/fsavatarrenderpersistence.h index 51481ea60b..1adf213e66 100644 --- a/indra/newview/fsavatarrenderpersistence.h +++ b/indra/newview/fsavatarrenderpersistence.h @@ -35,9 +35,11 @@ class FSAvatarRenderPersistence { LOG_CLASS(FSAvatarRenderPersistence); -friend class LLSingleton; friend class FSPanelPreferenceBackup; + LLSINGLETON(FSAvatarRenderPersistence); + virtual ~FSAvatarRenderPersistence(); + public: void init(); @@ -54,9 +56,6 @@ public: } private: - FSAvatarRenderPersistence(); - virtual ~FSAvatarRenderPersistence(); - void loadAvatarRenderSettings(); void saveAvatarRenderSettings(); diff --git a/indra/newview/fsdata.h b/indra/newview/fsdata.h index 27e7286158..16bb3dbf32 100644 --- a/indra/newview/fsdata.h +++ b/indra/newview/fsdata.h @@ -33,10 +33,11 @@ class FSData : public LLSingleton { - friend class LLSingleton; LOG_CLASS(FSData); + + LLSINGLETON(FSData); + public: - FSData(); void startDownload(); void downloadAgents(); diff --git a/indra/newview/fsfloatergrouptitles.h b/indra/newview/fsfloatergrouptitles.h index 24f7d89d10..24e42111f6 100644 --- a/indra/newview/fsfloatergrouptitles.h +++ b/indra/newview/fsfloatergrouptitles.h @@ -27,8 +27,6 @@ #ifndef FS_FLOATERGROUPTITLES_H #define FS_FLOATERGROUPTITLES_H -#include "llsingleton.h" - #include "llfloater.h" #include "llagent.h" @@ -51,7 +49,7 @@ protected: LLGroupData mGroupData; }; -class FSFloaterGroupTitles : public LLSingleton, public LLFloater, public LLGroupMgrObserver, public LLOldEvents::LLSimpleListener +class FSFloaterGroupTitles : public LLFloater, public LLGroupMgrObserver, public LLOldEvents::LLSimpleListener { public: diff --git a/indra/newview/fsfloaterimcontainer.cpp b/indra/newview/fsfloaterimcontainer.cpp index 1a3844aab9..20db1c537b 100644 --- a/indra/newview/fsfloaterimcontainer.cpp +++ b/indra/newview/fsfloaterimcontainer.cpp @@ -64,7 +64,7 @@ FSFloaterIMContainer::~FSFloaterIMContainer() mNewMessageConnection.disconnect(); LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); - if (!LLSingleton::destroyed()) + if (LLIMMgr::instanceExists()) { LLIMMgr::getInstance()->removeSessionObserver(this); } diff --git a/indra/newview/fsfloaterimport.cpp b/indra/newview/fsfloaterimport.cpp index 587e83c0b9..0a4bdc7fba 100644 --- a/indra/newview/fsfloaterimport.cpp +++ b/indra/newview/fsfloaterimport.cpp @@ -126,7 +126,7 @@ FSFloaterImport::~FSFloaterImport() BOOL FSFloaterImport::postBuild() { - if (LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() == 0 + if (LLGlobalEconomy::getInstance()->getPriceUpload() == 0 || gAgent.getRegion()->getCentralBakeVersion() > 0) { getChild("temp_asset")->setVisible(FALSE); @@ -520,7 +520,7 @@ void FSFloaterImport::onClickBtnImport() if (!getChild("temp_asset")->get()) { - U32 expected_upload_cost = mTexturesTotal * (U32)LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + U32 expected_upload_cost = mTexturesTotal * (U32)LLGlobalEconomy::getInstance()->getPriceUpload(); if(!(can_afford_transaction(expected_upload_cost))) { LLStringUtil::format_map_t args; @@ -590,7 +590,7 @@ void FSFloaterImport::onClickCheckBoxUploadAsset() { getChild("temp_asset")->setEnabled(TRUE); LLUIString stats = getString("upload_cost"); - stats.setArg("[COST]", llformat("%u", (mTexturesTotal + mSoundsTotal + mAnimsTotal) * (U32)LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + stats.setArg("[COST]", llformat("%u", (mTexturesTotal + mSoundsTotal + mAnimsTotal) * (U32)LLGlobalEconomy::getInstance()->getPriceUpload())); getChild("file_status_text")->setText(stats.getString()); } else @@ -613,7 +613,7 @@ void FSFloaterImport::onClickCheckBoxTempAsset() else { LLUIString stats = getString("upload_cost"); - stats.setArg("[COST]", llformat("%u", (mTexturesTotal + mSoundsTotal + mAnimsTotal) * (U32)LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + stats.setArg("[COST]", llformat("%u", (mTexturesTotal + mSoundsTotal + mAnimsTotal) * (U32)LLGlobalEconomy::getInstance()->getPriceUpload())); getChild("file_status_text")->setText(stats.getString()); } } @@ -1468,7 +1468,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item) data->mAssetInfo.mCreatorID = gAgentID; data->mInventoryType = inventory_type; data->mNextOwnerPerm = LLFloaterPerms::getNextOwnerPerms(perms_prefix); - data->mExpectedUploadCost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + data->mExpectedUploadCost = LLGlobalEconomy::getInstance()->getPriceUpload(); FSResourceData* fs_data = new FSResourceData; fs_data->uuid = asset_id; fs_data->mFloater = this; @@ -1960,7 +1960,7 @@ void uploadCoroutine( LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &a_httpAdapter { LLAssetType::EType asset_type = LLAssetType::lookup( aBody[ "asset_type" ].asString() ); LLInventoryType::EType inventory_type = LLInventoryType::lookup( aBody[ "inventory_type" ].asString() ); - S32 upload_price = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_price = LLGlobalEconomy::getInstance()->getPriceUpload(); const std::string inventory_type_string = aBody[ "asset_type" ].asString(); const LLUUID& item_folder_id = aBody[ "folder_id" ].asUUID(); diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp index f98e275d35..df1139c5bd 100644 --- a/indra/newview/fsfloatersearch.cpp +++ b/indra/newview/fsfloatersearch.cpp @@ -549,9 +549,9 @@ void FSFloaterSearch::displayEventDetails(U32 eventId, F64 eventEpoch, const std S32 region_x; S32 region_y; S32 region_z; - region_x = ll_round(eventGlobalPos.mdV[VX]) % REGION_WIDTH_UNITS; - region_y = ll_round(eventGlobalPos.mdV[VY]) % REGION_WIDTH_UNITS; - region_z = ll_round(eventGlobalPos.mdV[VZ]); + region_x = (S64)ll_round(eventGlobalPos.mdV[VX]) % REGION_WIDTH_UNITS; + region_y = (S64)ll_round(eventGlobalPos.mdV[VY]) % REGION_WIDTH_UNITS; + region_z = (S32)ll_round(eventGlobalPos.mdV[VZ]); LLStringUtil::format_map_t map; map["DURATION"] = llformat("%d:%.2d", eventDuration / 60, eventDuration % 60); map["LOCATION"] = llformat("%s (%d, %d, %d)", simName.c_str(), region_x, region_y, region_z); diff --git a/indra/newview/fsgridhandler.h b/indra/newview/fsgridhandler.h index 55210b492d..4fcb131924 100644 --- a/indra/newview/fsgridhandler.h +++ b/indra/newview/fsgridhandler.h @@ -101,6 +101,11 @@ protected: **/ class LLGridManager : public LLSingleton { + // when the grid manager is instantiated, the default grids are automatically + // loaded, and the grids favorites list is loaded from the xml file. + LLSINGLETON(LLGridManager); + ~LLGridManager(); + public: typedef enum { @@ -115,19 +120,14 @@ public: FAIL, REMOVE } AddState; - - // when the grid manager is instantiated, the default grids are automatically - // loaded, and the grids favorites list is loaded from the xml file. - LLGridManager(); - ~LLGridManager(); - + void initGrids(); void initSystemGrids(); void initGridList(std::string grid_file, AddState state); void initCmdLineGrids(); void resetGrids(); // grid list management - bool isReadyToLogin(){return mReadyToLogin;} + bool isReadyToLogin(){return mReadyToLogin;} // add a grid to the list of grids void addGrid(const std::string& loginuri); diff --git a/indra/newview/fskeywords.h b/indra/newview/fskeywords.h index f4e411aa7f..7e9208d60a 100644 --- a/indra/newview/fskeywords.h +++ b/indra/newview/fskeywords.h @@ -33,10 +33,10 @@ class LLChat; class FSKeywords : public LLSingleton { -public: - FSKeywords(); + LLSINGLETON(FSKeywords); virtual ~FSKeywords(); +public: void updateKeywords(); bool chatContainsKeyword(const LLChat& chat, bool is_local); void static notify(const LLChat& chat); // FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground diff --git a/indra/newview/fslightshare.h b/indra/newview/fslightshare.h index f3a47db393..05d66ea92a 100644 --- a/indra/newview/fslightshare.h +++ b/indra/newview/fslightshare.h @@ -132,12 +132,15 @@ struct LightsharePacket class FSLightshare : public LLSingleton { LOG_CLASS(FSLightshare); -public: - FSLightshare(); + + LLSINGLETON(FSLightshare); virtual ~FSLightshare(); + +public: void processLightshareMessage(LLMessageSystem* msg); void processLightshareReset(); bool getState() { return mLightshareState; }; + private: friend class LLSingleton; static void processWater(LightsharePacket* ls_packet); diff --git a/indra/newview/fslslbridge.h b/indra/newview/fslslbridge.h index 21c4b8c13c..9916b8b21a 100644 --- a/indra/newview/fslslbridge.h +++ b/indra/newview/fslslbridge.h @@ -50,10 +50,10 @@ class FSLSLBridge : public LLSingleton, public LLVOInventoryListene friend class FSLSLBridgeReAttachTimer; friend class FSLSLBridgeStartCreationTimer; -public: - FSLSLBridge(); + LLSINGLETON(FSLSLBridge); ~FSLSLBridge(); +public: typedef boost::function tCallback; bool lslToViewer(const std::string& message, const LLUUID& fromID, const LLUUID& ownerID); diff --git a/indra/newview/fsnearbychathub.h b/indra/newview/fsnearbychathub.h index fc9ceafc6f..9c59cdd334 100644 --- a/indra/newview/fsnearbychathub.h +++ b/indra/newview/fsnearbychathub.h @@ -36,10 +36,7 @@ class LLUICtrl; class FSNearbyChat : public LLSingleton { - friend class LLSingleton; - -private: - FSNearbyChat(); + LLSINGLETON(FSNearbyChat); ~FSNearbyChat(); void sendMsg(); diff --git a/indra/newview/fspose.h b/indra/newview/fspose.h index 657e044b92..875b32702d 100644 --- a/indra/newview/fspose.h +++ b/indra/newview/fspose.h @@ -17,14 +17,15 @@ class FSPose : public LLSingleton { - friend class LLSingleton; LOG_CLASS(FSPose); + + LLSINGLETON(FSPose); + ~FSPose(); + public: void setPose(const std::string& new_pose, bool save_state = true); void stopPose(); -protected: - FSPose(); - ~FSPose(); + private: LLUUID mCurrentPose; }; diff --git a/indra/newview/fsradar.h b/indra/newview/fsradar.h index 9d44afa374..44356924e8 100644 --- a/indra/newview/fsradar.h +++ b/indra/newview/fsradar.h @@ -59,7 +59,8 @@ class FSRadar { LOG_CLASS(FSRadar); -friend class LLSingleton; + LLSINGLETON(FSRadar); + virtual ~FSRadar(); public: typedef boost::unordered_map entry_map_t; @@ -108,9 +109,6 @@ public: } private: - FSRadar(); - virtual ~FSRadar(); - void updateRadarList(); void updateTracking(); void checkTracking(); diff --git a/indra/newview/kcwlinterface.h b/indra/newview/kcwlinterface.h index b9c5d34681..542e2172a1 100644 --- a/indra/newview/kcwlinterface.h +++ b/indra/newview/kcwlinterface.h @@ -38,10 +38,11 @@ class KCWindlightInterface : public LLSingleton, LLEventTi { LOG_CLASS(KCWindlightInterface); -public: - KCWindlightInterface(); + LLSINGLETON(KCWindlightInterface); ~KCWindlightInterface(); +public: + void parcelChange(); /*virtual*/ BOOL tick(); // From LLEventTime diff --git a/indra/newview/lfsimfeaturehandler.h b/indra/newview/lfsimfeaturehandler.h index 37522f26c4..e2caf0c99c 100644 --- a/indra/newview/lfsimfeaturehandler.h +++ b/indra/newview/lfsimfeaturehandler.h @@ -57,9 +57,7 @@ class LFSimFeatureHandler : public LLSingleton { LOG_CLASS(LFSimFeatureHandler); -protected: - friend class LLSingleton; - LFSimFeatureHandler(); + LLSINGLETON(LFSimFeatureHandler); public: void handleRegionChange(); diff --git a/indra/newview/lggcontactsets.cpp b/indra/newview/lggcontactsets.cpp index dfa91a698a..b3c291f9bd 100644 --- a/indra/newview/lggcontactsets.cpp +++ b/indra/newview/lggcontactsets.cpp @@ -31,6 +31,8 @@ #include "llnotifications.h" #include "llnotificationsutil.h" #include "llsdserialize.h" +#include "lluicolor.h" +#include "lluicolortable.h" #include "llviewercontrol.h" #include "llvoavatar.h" #include "fsdata.h" @@ -321,13 +323,13 @@ LLColor4 LGGContactSets::colorize(const LLUUID& uuid, const LLColor4& cur_color, { case LGG_CS_CHAT: case LGG_CS_IM: - color = LLUIColorTable::instance().getColor("UserChatColor", LLColor4::white); + color = LLUIColorTable::instance().getColor("UserChatColor", LLColor4::white).get(); break; case LGG_CS_TAG: - color = LLUIColorTable::instance().getColor("NameTagSelf", LLColor4::white); + color = LLUIColorTable::instance().getColor("NameTagSelf", LLColor4::white).get(); break; case LGG_CS_MINIMAP: - color = LLUIColorTable::instance().getColor("MapAvatarSelfColor", LLColor4::white); + color = LLUIColorTable::instance().getColor("MapAvatarSelfColor", LLColor4::white).get(); break; case LGG_CS_RADAR: default: @@ -341,28 +343,28 @@ LLColor4 LGGContactSets::colorize(const LLUUID& uuid, const LLColor4& cur_color, { case LGG_CS_CHAT: if (!rlv_shownames) - color = LLUIColorTable::instance().getColor("FriendsChatColor", LLColor4::white); + color = LLUIColorTable::instance().getColor("FriendsChatColor", LLColor4::white).get(); break; case LGG_CS_IM: - color = LLUIColorTable::instance().getColor("FriendsChatColor", LLColor4::white); + color = LLUIColorTable::instance().getColor("FriendsChatColor", LLColor4::white).get(); break; case LGG_CS_TAG: { // This is optional per prefs. - static LLUICachedControl color_friends("NameTagShowFriends"); + static LLCachedControl color_friends(gSavedSettings, "NameTagShowFriends"); if (color_friends && !rlv_shownames) { - color = LLUIColorTable::instance().getColor("NameTagFriend", LLColor4::white); + color = LLUIColorTable::instance().getColor("NameTagFriend", LLColor4::white).get(); } } break; case LGG_CS_MINIMAP: if (!rlv_shownames) - color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); + color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white).get(); break; case LGG_CS_RADAR: if (legacy_radar_friend && !rlv_shownames) - color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); + color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white).get(); break; default: LL_DEBUGS("ContactSets") << "Unhandled colorize case!" << LL_ENDL; @@ -379,13 +381,13 @@ LLColor4 LGGContactSets::colorize(const LLUUID& uuid, const LLColor4& cur_color, { case LGG_CS_CHAT: case LGG_CS_IM: - color = LLUIColorTable::instance().getColor("MutedChatColor", LLColor4::grey3); + color = LLUIColorTable::instance().getColor("MutedChatColor", LLColor4::grey3).get(); break; case LGG_CS_TAG: - color = LLUIColorTable::instance().getColor("NameTagMuted", LLColor4::grey3); + color = LLUIColorTable::instance().getColor("NameTagMuted", LLColor4::grey3).get(); break; case LGG_CS_MINIMAP: - color = LLUIColorTable::instance().getColor("MapAvatarMutedColor", LLColor4::grey3); + color = LLUIColorTable::instance().getColor("MapAvatarMutedColor", LLColor4::grey3).get(); break; case LGG_CS_RADAR: default: @@ -399,13 +401,13 @@ LLColor4 LGGContactSets::colorize(const LLUUID& uuid, const LLColor4& cur_color, { case LGG_CS_CHAT: case LGG_CS_IM: - color = LLUIColorTable::instance().getColor("FirestormChatColor", LLColor4::red); + color = LLUIColorTable::instance().getColor("FirestormChatColor", LLColor4::red).get(); break; case LGG_CS_TAG: - color = LLUIColorTable::instance().getColor("NameTagFirestorm", LLColor4::red); + color = LLUIColorTable::instance().getColor("NameTagFirestorm", LLColor4::red).get(); break; case LGG_CS_MINIMAP: - color = LLUIColorTable::instance().getColor("MapAvatarFirestormColor", LLColor4::red); + color = LLUIColorTable::instance().getColor("MapAvatarFirestormColor", LLColor4::red).get(); break; case LGG_CS_RADAR: default: @@ -422,17 +424,17 @@ LLColor4 LGGContactSets::colorize(const LLUUID& uuid, const LLColor4& cur_color, { case LGG_CS_CHAT: case LGG_CS_IM: - color = LLUIColorTable::instance().getColor("LindenChatColor", LLColor4::blue); + color = LLUIColorTable::instance().getColor("LindenChatColor", LLColor4::blue).get(); break; case LGG_CS_TAG: - color = LLUIColorTable::instance().getColor("NameTagLinden", LLColor4::blue); + color = LLUIColorTable::instance().getColor("NameTagLinden", LLColor4::blue).get(); break; case LGG_CS_MINIMAP: - color = LLUIColorTable::instance().getColor("MapAvatarLindenColor", LLColor4::blue); + color = LLUIColorTable::instance().getColor("MapAvatarLindenColor", LLColor4::blue).get(); break; case LGG_CS_RADAR: if (legacy_radar_linden) - color = LLUIColorTable::instance().getColor("MapAvatarLindenColor", LLColor4::blue); + color = LLUIColorTable::instance().getColor("MapAvatarLindenColor", LLColor4::blue).get(); break; default: LL_DEBUGS("ContactSets") << "Unhandled colorize case!" << LL_ENDL; diff --git a/indra/newview/lggcontactsets.h b/indra/newview/lggcontactsets.h index 07b7d40e89..3fcb3a265d 100644 --- a/indra/newview/lggcontactsets.h +++ b/indra/newview/lggcontactsets.h @@ -44,9 +44,11 @@ const std::string CS_PSEUDONYM = "--- ---"; class LGGContactSets : public LLSingleton { - friend class LLSingleton; LOG_CLASS(LGGContactSets); + LLSINGLETON(LGGContactSets); + ~LGGContactSets(); + public: typedef std::vector string_vec_t; typedef boost::unordered_set uuid_set_t; @@ -136,9 +138,6 @@ public: // [/FS:CR] private: - LGGContactSets(); - ~LGGContactSets(); - void toneDownColor(LLColor4& color) const; uuid_vec_t getFriendsInSet(const std::string& set_name); uuid_vec_t getFriendsInAnySet(); 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/llagentwearables.h b/indra/newview/llagentwearables.h index 33af0b18dc..835fa7242a 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -38,6 +38,7 @@ #include "llviewerinventory.h" #include "llavatarappearancedefines.h" #include "llwearabledata.h" +#include "llinitdestroyclass.h" class LLInventoryItem; class LLVOAvatarSelf; diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index aa0ced430d..1432567489 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -73,7 +73,7 @@ frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(oneFrame) userInfo:nil repeats:YES]; } else { - handleQuit(); + exit(0); } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 51b9979c77..211b6da64a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -4508,7 +4508,6 @@ LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), mOutfitIsDirty(false), mOutfitLocked(false), - mInFlightCounter(0), mInFlightTimer(), mIsInUpdateAppearanceFromCOF(false), mOutstandingAppearanceBakeRequest(false), diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 5ea8a77181..8b339f11c5 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: @@ -266,10 +267,6 @@ private: static void debugAppearanceUpdateCOF(const LLSD& content); std::string mAppearanceServiceURL; - -protected: - LLAppearanceMgr(); - ~LLAppearanceMgr(); private: @@ -297,7 +294,6 @@ private: * to avoid unsynchronized outfit state or performing duplicate operations. */ bool mOutfitLocked; - S32 mInFlightCounter; LLTimer mInFlightTimer; static bool mActive; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7aee8b2ff6..f81f700e65 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -252,6 +252,7 @@ #include "llsecapi.h" #include "llmachineid.h" #include "llmainlooprepeater.h" +#include "llcleanup.h" #include "llcoproceduremanager.h" #include "llviewereventrecorder.h" @@ -451,6 +452,7 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; */ class LLDeferredTaskList: public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList); LOG_CLASS(LLDeferredTaskList); friend class LLAppViewer; @@ -825,7 +827,7 @@ LLAppViewer::LLAppViewer() LLAppViewer::~LLAppViewer() { delete mSettingsLocationList; - LLViewerEventRecorder::instance().~LLViewerEventRecorder(); + LLViewerEventRecorder::deleteSingleton(); LLLoginInstance::instance().setUpdaterService(0); @@ -2073,7 +2075,7 @@ bool LLAppViewer::cleanup() gTransferManager.cleanup(); #endif - LLLocalBitmapMgr::cleanupClass(); + SUBSYSTEM_CLEANUP(LLLocalBitmapMgr); // Note: this is where gWorldMap used to be deleted. @@ -2189,12 +2191,12 @@ bool LLAppViewer::cleanup() LLViewerObject::cleanupVOClasses(); - LLAvatarAppearance::cleanupClass(); + SUBSYSTEM_CLEANUP(LLAvatarAppearance); // Comment out duplicate clean up - //LLAvatarAppearance::cleanupClass(); + //SUBSYSTEM_CLEANUP(LLAvatarAppearance); - LLPostProcess::cleanupClass(); + SUBSYSTEM_CLEANUP(LLPostProcess); LLTracker::cleanupInstance(); @@ -2220,12 +2222,12 @@ bool LLAppViewer::cleanup() //end_messaging_system(); - LLFollowCamMgr::cleanupClass(); - //LLVolumeMgr::cleanupClass(); + SUBSYSTEM_CLEANUP(LLFollowCamMgr); + //SUBSYSTEM_CLEANUP(LLVolumeMgr); LLPrimitive::cleanupVolumeManager(); - LLWorldMapView::cleanupClass(); - LLFolderViewItem::cleanupClass(); - LLUI::cleanupClass(); + SUBSYSTEM_CLEANUP(LLWorldMapView); + SUBSYSTEM_CLEANUP(LLFolderViewItem); + SUBSYSTEM_CLEANUP(LLUI); // // Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles). @@ -2234,7 +2236,7 @@ bool LLAppViewer::cleanup() // LL_INFOS() << "Cleaning up VFS" << LL_ENDL; - LLVFile::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVFile); LL_INFOS() << "Saving Data" << LL_ENDL; @@ -2375,9 +2377,9 @@ bool LLAppViewer::cleanup() // Non-LLCurl libcurl library mAppCoreHttp.cleanup(); - LLFilePickerThread::cleanupClass(); + SUBSYSTEM_CLEANUP(LLFilePickerThread); - //MUST happen AFTER LLCurl::cleanupClass + //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl) delete sTextureCache; sTextureCache = NULL; delete sTextureFetch; @@ -2401,22 +2403,22 @@ bool LLAppViewer::cleanup() gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); } - LLMetricPerformanceTesterBasic::cleanClass() ; + SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ; LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL; //Note: - //LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown() + //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown() //because some new image might be generated during cleaning up media. --bao - LLViewerMedia::cleanupClass(); - LLViewerParcelMedia::cleanupClass(); + SUBSYSTEM_CLEANUP(LLViewerMedia); + SUBSYSTEM_CLEANUP(LLViewerParcelMedia); gTextureList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); // This should eventually be done in LLAppViewer - LLImage::cleanupClass(); - LLVFSThread::cleanupClass(); - LLLFSThread::cleanupClass(); + SUBSYSTEM_CLEANUP(LLImage); + SUBSYSTEM_CLEANUP(LLVFSThread); + SUBSYSTEM_CLEANUP(LLLFSThread); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_INFOS() << "Auditing VFS" << LL_ENDL; @@ -2459,10 +2461,10 @@ bool LLAppViewer::cleanup() LL_INFOS() << "File launched." << LL_ENDL; } LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL; - LLProxy::cleanupClass(); + SUBSYSTEM_CLEANUP(LLProxy); LLCore::LLHttp::cleanup(); - LLWearableType::cleanupClass(); + SUBSYSTEM_CLEANUP(LLWearableType); LLMainLoopRepeater::instance().stop(); @@ -2474,10 +2476,34 @@ bool LLAppViewer::cleanup() LLError::LLCallStacks::cleanup(); removeMarkerFiles(); - - LL_INFOS() << "Goodbye!" << LL_ENDL; - removeDumpDir(); + // It's not at first obvious where, in this long sequence, generic cleanup + // calls OUGHT to go. So let's say this: as we migrate cleanup from + // explicit hand-placed calls into the generic mechanism, eventually + // all cleanup will get subsumed into the generic calls. So the calls you + // still see above are calls that MUST happen before the generic cleanup + // kicks in. + + // This calls every remaining LLSingleton's cleanupSingleton() method. + // This method should perform any cleanup that might take significant + // realtime, or might throw an exception. + LLSingletonBase::cleanupAll(); + + // This calls every remaining LLSingleton's deleteSingleton() method. + // No class destructor should perform any cleanup that might take + // significant realtime, or throw an exception. + // LLSingleton machinery includes a last-gasp implicit deleteAll() call, + // so this explicit call shouldn't strictly be necessary. However, by the + // time the runtime engages that implicit call, it may already have + // destroyed things like std::cerr -- so the implicit deleteAll() refrains + // from logging anything. Since both cleanupAll() and deleteAll() call + // their respective cleanup methods in computed dependency order, it's + // probably useful to be able to log that order. + LLSingletonBase::deleteAll(); + + LL_INFOS() << "Goodbye!" << LL_ENDL; + + removeDumpDir(); // return 0; return true; @@ -6368,9 +6394,12 @@ void LLAppViewer::disconnectViewer() } saveNameCache(); - LLExperienceCache *expCache = LLExperienceCache::getIfExists(); - if (expCache) - expCache->cleanup(); + if (LLExperienceCache::instanceExists()) + { + // TODO: LLExperienceCache::cleanup() logic should be moved to + // cleanupSingleton(). + LLExperienceCache::instance().cleanup(); + } // close inventory interface, close all windows // Clean up inventory windows on shutdown diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h index d44c113f78..d9ffdca7ba 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(); - // [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1) void addAttachmentRequest(const LLUUID& item_id, const U8 attachment_pt, 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 50eee37bb6..24893eee70 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -892,6 +892,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 75d6175254..7c0e570d89 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 63be987890..7eff1de051 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -203,13 +203,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 a169baef40..ec17b3d9e6 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -67,9 +67,9 @@ typedef std::list hud_complexity_list_t; // 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(); @@ -114,10 +114,10 @@ private: // Class to notify user about heavy set of HUD class LLHUDRenderNotifier : public LLSingleton { -public: - LLHUDRenderNotifier(); + LLSINGLETON(LLHUDRenderNotifier); ~LLHUDRenderNotifier(); +public: void updateNotificationHUD(hud_complexity_list_t complexity); 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/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index dd07f7bcec..ebedee65ee 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -263,6 +263,32 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) } } + S32 chars_in_line = mMsgText->getRect().getWidth() / messageFont->getWidth("c"); + S32 max_lines = notification["available_height"].asInteger() / (mMsgText->getTextPixelHeight() + 4); + S32 new_line_chars = std::count(messageText.begin(), messageText.end(), '\n'); + S32 lines_count = (messageText.size() - new_line_chars) / chars_in_line + new_line_chars + 1; + + //Remove excessive chars if message is not fit in available height. MAINT-6891 + if(lines_count > max_lines) + { + while(lines_count > max_lines) + { + std::size_t nl_pos = messageText.rfind('\n'); + if (nl_pos != std::string::npos) + { + nl_pos = nl_pos > messageText.length() - chars_in_line? nl_pos : messageText.length() - chars_in_line; + messageText.erase(messageText.begin() + nl_pos, messageText.end()); + } + else + { + messageText.erase(messageText.end() - chars_in_line, messageText.end()); + } + new_line_chars = std::count(messageText.begin(), messageText.end(), '\n'); + lines_count = (messageText.size() - new_line_chars) / chars_in_line + new_line_chars; + } + messageText += " ..."; + } + //append text { LLStyle::Params style_params; diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index f537a947e1..6b931e0468 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -42,7 +42,7 @@ namespace const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; } -LLChicletBar::LLChicletBar(const LLSD&) +LLChicletBar::LLChicletBar() : mChicletPanel(NULL), mToolbarStack(NULL) { @@ -58,7 +58,7 @@ LLChicletBar::LLChicletBar(const LLSD&) // [FS communication UI] LLChicletBar::~LLChicletBar() { - if (!LLSingleton::destroyed()) + if (LLIMMgr::instanceExists()) { LLIMMgr::getInstance()->removeSessionObserver(this); } diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h index 2f634b49a9..d54af7d06a 100644 --- a/indra/newview/llchicletbar.h +++ b/indra/newview/llchicletbar.h @@ -41,8 +41,9 @@ class LLChicletBar // [FS communication UI] , public LLIMSessionObserver { + LLSINGLETON(LLChicletBar); LOG_CLASS(LLChicletBar); - friend class LLSingleton; + public: // [FS communication UI] ~LLChicletBar(); @@ -105,8 +106,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 81b31dc71c..73bbe05c4c 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: @@ -69,7 +70,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 5bb8576451..087c622ffb 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/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index f23c3cadd3..3a1f9fe484 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -419,7 +419,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) if ((params.mVertexBuffer->getTypeMask() & mask) != mask) { //FIXME! - LL_WARNS() << "Missing required components, skipping render batch." << LL_ENDL; + LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask + << " present: " << (params.mVertexBuffer->getTypeMask() & mask) + << ". Skipping render batch." << LL_ENDL; continue; } diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index da3ffe5f2e..96bcc771c7 100644 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -246,14 +246,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; @@ -319,7 +318,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 d000b16ef2..21e13c3d9d 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -34,6 +34,7 @@ #include "llinventoryobserver.h" #include "llinventorymodel.h" #include "llviewerinventory.h" +#include "llinitdestroyclass.h" class LLMenuItemCallGL; class LLToggleableMenu; @@ -180,6 +181,7 @@ private: class LLFavoritesOrderStorage : public LLSingleton , public LLDestroyClass { + LLSINGLETON(LLFavoritesOrderStorage); LOG_CLASS(LLFavoritesOrderStorage); public: /** @@ -228,10 +230,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. */ @@ -281,4 +279,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/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index a29ccf2b6d..f2af9b5300 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -93,4 +93,9 @@ void LLFilteredWearableListManager::populateList() mWearableList->refreshList(item_array); } +void LLFilteredWearableListManager::holdProgress() +{ + mWearableList->setForceRefresh(false); +} + // EOF diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h index c21458ca98..f44ab1466f 100644 --- a/indra/newview/llfilteredwearablelist.h +++ b/indra/newview/llfilteredwearablelist.h @@ -56,6 +56,11 @@ public: */ void populateList(); + /** + * Drop operation + */ + void holdProgress(); + private: LLInventoryItemsList* mWearableList; LLInventoryCollectFunctor* mCollector; diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h index b8af23f609..5374cb7fa9 100644 --- a/indra/newview/llflickrconnect.h +++ b/indra/newview/llflickrconnect.h @@ -46,6 +46,8 @@ const U32 FLICKR_CONNECT_TIMEOUT = 600; */ class LLFlickrConnect : public LLSingleton { + LLSINGLETON(LLFlickrConnect); + ~LLFlickrConnect() {}; LOG_CLASS(LLFlickrConnect); public: enum EConnectionState @@ -83,10 +85,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/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index ad97f0a495..7889227153 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1365,7 +1365,7 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata) { std::string name = floaterp->getChild("name_form")->getValue().asString(); std::string desc = floaterp->getChild("description_form")->getValue().asString(); - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo( floaterp->mTransactionID, LLAssetType::AT_ANIMATION, diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 64b1c1fc2c..0dd826f4e4 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -123,7 +123,7 @@ BOOL LLFloaterImagePreview::postBuild() getChildView("lossless_check")->setEnabled(TRUE); // Temporary texture uploads - BOOL enable_temp_uploads = (LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() != 0 + BOOL enable_temp_uploads = (LLGlobalEconomy::getInstance()->getPriceUpload() != 0 && gAgent.getRegion()->getCentralBakeVersion() == 0); if (!enable_temp_uploads) { diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 31a892d3b2..f9ab84c85f 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -102,7 +102,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer() gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed()); gSavedPerAccountSettings.setBOOL("ConversationsParticipantListCollapsed", !isParticipantListExpanded()); - if (!LLSingleton::destroyed()) + if (LLIMMgr::instanceExists()) { LLIMMgr::getInstance()->removeSessionObserver(this); } diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index bfe543a76a..ac5c8fab57 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -335,6 +335,14 @@ void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat) if(mStopProcessing) return; + if (mFloaterSnapRegion == NULL) + { + mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region"); + } + LLRect channel_rect; + mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView); + chat["available_height"] = channel_rect.getHeight() - channel_rect.mBottom - gSavedSettings.getS32("ToastGap") - 110;; + /* find last toast and check ID */ @@ -436,7 +444,7 @@ void LLFloaterIMNearbyChatScreenChannel::arrangeToasts() setFollows(FOLLOWS_ALL); } - LLRect toast_rect; + LLRect toast_rect; updateRect(); LLRect channel_rect; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index e7c299c416..5a18776833 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1850,8 +1850,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable // this is the initial file picking. Close the whole floater // if we don't have a base model to show for high LOD. mFMP->closeFloater(false); - mLoading = false; } + mLoading = false; return; } @@ -2239,14 +2239,11 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) if (!mBaseModel.empty()) { const std::string& model_name = mBaseModel[0]->getName(); - // FIRE-20309: Mesh model name gets overwritten when selecting LOD/Physics file - //mFMP->getChild("description_form")->setValue(model_name); LLLineEditor* description_form = mFMP->getChild("description_form"); if (description_form->getText().empty()) { description_form->setText(model_name); } - // } } refresh(); @@ -4668,4 +4665,12 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(S32 status, const std::stri LLNotificationsUtil::add("MeshUploadPermError"); } +bool LLFloaterModelPreview::isModelLoading() +{ + if(mModelPreview) + { + return mModelPreview->mLoading; + } + return false; +} diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 2271e48de4..2b3038a3f8 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -115,6 +115,8 @@ public: void enableViewOption(const std::string& option); void disableViewOption(const std::string& option); + bool isModelLoading(); + // shows warning message if agent has no permissions to upload model /*virtual*/ void onPermissionsReceived(const LLSD& result); diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 4a5732aecf..c9a689281e 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -123,7 +123,7 @@ BOOL LLFloaterNameDesc::postBuild() // Cancel button getChild("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this)); - getChild("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() )); + getChild("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload() )); setDefaultBtn("ok_btn"); @@ -162,7 +162,7 @@ void LLFloaterNameDesc::onBtnOK( ) getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads LLAssetStorage::LLStoreAssetCallback callback = NULL; - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). if (can_afford_transaction(expected_upload_cost)) { diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 280808e545..55e47efca3 100644 --- a/indra/newview/llfloaterpay.cpp +++ b/indra/newview/llfloaterpay.cpp @@ -302,8 +302,6 @@ void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata) self->mQuickPayButton[i]->setLabelUnselected(button_str); self->mQuickPayButton[i]->setVisible(TRUE); self->mQuickPayInfo[i]->mAmount = pay_button; - // Control doesn't exist as of 2015-01-27 - //self->getChildView("fastpay text")->setVisible(TRUE); if ( pay_button > max_pay_amount ) { @@ -431,8 +429,6 @@ void LLFloaterPay::payDirectly(money_callback callback, floater->getChildView("pay btn")->setVisible(TRUE); floater->getChildView("amount text")->setVisible(TRUE); - // Control doesn't exist as of 2015-01-27 - //floater->getChildView("fastpay text")->setVisible(TRUE); for(S32 i=0;imQuickPayButton[i]->setVisible(TRUE); @@ -619,9 +615,8 @@ void LLFloaterPay::give(S32 amount) else { // just transfer the L$ - // Ansariel: Added custom payment message std::string paymentMessage(getChild("payment_message")->getValue().asString()); - mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, (paymentMessage == "" ? LLStringUtil::null : paymentMessage)); + mCallback(mTargetUUID, gAgent.getRegion(), amount, mTargetIsGroup, TRANS_GIFT, (paymentMessage.empty() ? LLStringUtil::null : paymentMessage)); // check if the payee needs to be unmuted LLMuteList::getInstance()->autoRemove(mTargetUUID, LLMuteList::AR_MONEY); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 11d3170af3..8282dd0db0 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -37,6 +37,7 @@ #include "llcachename.h" #include "llcheckboxctrl.h" #include "llfontgl.h" +#include "llimagebmp.h" #include "llimagej2c.h" #include "llinventory.h" #include "llnotificationsutil.h" @@ -76,6 +77,7 @@ #include "llselectmgr.h" #include "llversioninfo.h" #include "lluictrlfactory.h" +#include "llviewercontrol.h" #include "llviewernetwork.h" #include "llagentui.h" @@ -86,6 +88,7 @@ #include "llcorehttputil.h" #include "llviewerassetupload.h" +const std::string SCREEN_PREV_FILENAME = "screen_report_last.bmp"; //========================================================================= //----------------------------------------------------------------------------- @@ -181,11 +184,6 @@ BOOL LLFloaterReporter::postBuild() } setPosBox(pos); - // Take a screenshot, but don't draw this floater. - setVisible(FALSE); - takeScreenshot(); - setVisible(TRUE); - // Default text to be blank getChild("object_name")->setValue(LLStringUtil::null); getChild("owner_name")->setValue(LLStringUtil::null); @@ -780,18 +778,24 @@ void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url } } -void LLFloaterReporter::takeScreenshot() +void LLFloaterReporter::takeScreenshot(bool use_prev_screenshot) { - const S32 IMAGE_WIDTH = 1024; - const S32 IMAGE_HEIGHT = 768; - - LLPointer raw = new LLImageRaw; - if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE)) + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", TRUE); + if(!use_prev_screenshot) { - LL_WARNS() << "Unable to take screenshot" << LL_ENDL; - return; + std::string screenshot_filename(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + SCREEN_PREV_FILENAME); + LLPointer bmp_image = new LLImageBMP; + if(bmp_image->encode(mImageRaw, 0.0f)) + { + bmp_image->save(screenshot_filename); + } } - LLPointer upload_data = LLViewerTextureList::convertToUploadFile(raw); + else + { + mImageRaw = mPrevImageRaw; + } + + LLPointer upload_data = LLViewerTextureList::convertToUploadFile(mImageRaw); // create a resource data mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; @@ -823,7 +827,7 @@ void LLFloaterReporter::takeScreenshot() // store in the image list so it doesn't try to fetch from the server LLPointer image_in_list = LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid); - image_in_list->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER); + image_in_list->createGLTexture(0, mImageRaw, 0, TRUE, LLGLTexture::OTHER); // the texture picker then uses that texture LLTextureCtrl* texture = getChild("screenshot"); @@ -834,7 +838,46 @@ void LLFloaterReporter::takeScreenshot() // Don't need the caption - should be obvious and messes up layout //texture->setCaption(getString("Screenshot")); } +} +void LLFloaterReporter::onOpen(const LLSD& key) +{ + mImageRaw = new LLImageRaw; + const S32 IMAGE_WIDTH = 1024; + const S32 IMAGE_HEIGHT = 768; + + // Take a screenshot, but don't draw this floater. + setVisible(FALSE); + if( !gViewerWindow->rawSnapshot(mImageRaw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE)) + { + LL_WARNS() << "Unable to take screenshot" << LL_ENDL; + setVisible(TRUE); + return; + } + setVisible(TRUE); + + if(gSavedPerAccountSettings.getBOOL("PreviousScreenshotForReport")) + { + std::string screenshot_filename(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + SCREEN_PREV_FILENAME); + mPrevImageRaw = new LLImageRaw; + LLPointer start_image_bmp = new LLImageBMP; + if(start_image_bmp->load(screenshot_filename)) + { + if (start_image_bmp->decode(mPrevImageRaw, 0.0f)) + { + LLNotificationsUtil::add("LoadPreviousReportScreenshot", LLSD(), LLSD(), boost::bind(&LLFloaterReporter::onLoadScreenshotDialog,this, _1, _2)); + return; + } + } + } + + takeScreenshot(); +} + +void LLFloaterReporter::onLoadScreenshotDialog(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + takeScreenshot(option == 0); } void LLFloaterReporter::uploadImage() @@ -898,6 +941,11 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos) getChild("pos_field")->setValue(pos_string); } +void LLFloaterReporter::onClose(bool app_quitting) +{ + gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting); +} + // FIRE-15368: Don't include floater in screenshot update void LLFloaterReporter::onUpdateScreenshot() { diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index bd3fd83e2e..d026687bc2 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -81,6 +81,8 @@ public: LLFloaterReporter(const LLSD& key); /*virtual*/ ~LLFloaterReporter(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); virtual void draw(); void setReportType(EReportType type) { mReportType = type; } @@ -103,10 +105,12 @@ public: void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id); + void onLoadScreenshotDialog(const LLSD& notification, const LLSD& response); + private: static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null); - void takeScreenshot(); + void takeScreenshot(bool use_prev_screenshot = false); void sendReportViaCaps(std::string url); void uploadImage(); bool validateReport(); @@ -142,6 +146,9 @@ private: std::string mDefaultSummary; LLResourceData* mResourceDatap; boost::signals2::connection mAvatarNameCacheConnection; + + LLPointer mImageRaw; + LLPointer mPrevImageRaw; }; #endif diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index d54232df82..945ac77c8b 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: @@ -100,8 +101,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 ed35a4880e..94c5df67eb 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -358,6 +358,8 @@ struct LLRoleActionSet class LLGroupMgr : public LLSingleton { + LLSINGLETON(LLGroupMgr); + ~LLGroupMgr(); LOG_CLASS(LLGroupMgr); public: @@ -379,8 +381,6 @@ public: public: - LLGroupMgr(); - ~LLGroupMgr(); void addObserver(LLGroupMgrObserver* observer); void addObserver(const LLUUID& group_id, LLParticularGroupObserver* observer); diff --git a/indra/newview/llhints.h b/indra/newview/llhints.h index ebffe561b9..dd6195a9ce 100644 --- a/indra/newview/llhints.h +++ b/indra/newview/llhints.h @@ -29,6 +29,7 @@ #include "llpanel.h" #include "llnotifications.h" +#include "llinitdestroyclass.h" class LLHints : public LLInitClass 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 85d98b5201..737bd25bee 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -33,6 +33,7 @@ #include "lllogchat.h" #include "llvoicechannel.h" +#include "llinitdestroyclass.h" #include "llcoros.h" #include "lleventcoro.h" @@ -61,6 +62,7 @@ private: */ class LLIMModel : public LLSingleton { + LLSINGLETON(LLIMModel); public: struct LLIMSession : public boost::signals2::trackable @@ -166,7 +168,6 @@ public: }; - LLIMModel(); // [FS communication UI] Re-added to not toast if our IM floater is active //we should control the currently active session @@ -351,6 +352,7 @@ public: class LLIMMgr : public LLSingleton { + LLSINGLETON(LLIMMgr); friend class LLIMModel; public: @@ -361,8 +363,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 1f613c1201..2f5a83840e 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/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 36e1cc97d1..1dc1aa395e 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -45,7 +45,7 @@ LLInventoryItemsList::Params::Params() LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p) : LLFlatListViewEx(p) -, mNeedsRefresh(false) +, mRefreshState(REFRESH_COMPLETE) , mForceRefresh(false) { // TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView @@ -66,13 +66,13 @@ LLInventoryItemsList::~LLInventoryItemsList() void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array) { - getIDs().clear(); + getIDs().clear(); LLInventoryModel::item_array_t::const_iterator it = item_array.begin(); for( ; item_array.end() != it; ++it) { getIDs().push_back((*it)->getUUID()); } - mNeedsRefresh = true; + mRefreshState = REFRESH_ALL; } boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb) @@ -113,9 +113,9 @@ void LLInventoryItemsList::updateSelection() void LLInventoryItemsList::doIdle() { - if (!mNeedsRefresh) return; + if (mRefreshState == REFRESH_COMPLETE) return; - if (isInVisibleChain() || mForceRefresh) + if (isInVisibleChain() || mForceRefresh ) { refresh(); @@ -137,54 +137,130 @@ LLTrace::BlockTimerStatHandle FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refres void LLInventoryItemsList::refresh() { - LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH); - static const unsigned ADD_LIMIT = 20; + LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH); - uuid_vec_t added_items; - uuid_vec_t removed_items; + switch (mRefreshState) + { + case REFRESH_ALL: + { + mAddedItems.clear(); + mRemovedItems.clear(); + computeDifference(getIDs(), mAddedItems, mRemovedItems); + if (mRemovedItems.size() > 0) + { + mRefreshState = REFRESH_LIST_ERASE; + } + else if (mAddedItems.size() > 0) + { + mRefreshState = REFRESH_LIST_APPEND; + } + else + { + mRefreshState = REFRESH_LIST_SORT; + } - computeDifference(getIDs(), added_items, removed_items); + rearrangeItems(); + notifyParentItemsRectChanged(); + break; + } + case REFRESH_LIST_ERASE: + { + uuid_vec_t::const_iterator it = mRemovedItems.begin(); + for (; mRemovedItems.end() != it; ++it) + { + // don't filter items right away + removeItemByUUID(*it, false); + } + mRemovedItems.clear(); + mRefreshState = REFRESH_LIST_SORT; // fix visibility and arrange + break; + } + case REFRESH_LIST_APPEND: + { + static const unsigned ADD_LIMIT = 25; // Note: affects perfomance - bool add_limit_exceeded = false; - unsigned int nadded = 0; + unsigned int nadded = 0; - uuid_vec_t::const_iterator it = added_items.begin(); - for( ; added_items.end() != it; ++it) - { - if(nadded >= ADD_LIMIT) - { - add_limit_exceeded = true; - break; - } - LLViewerInventoryItem* item = gInventory.getItem(*it); - // Do not rearrange items on each adding, let's do that on filter call - llassert(item); - if (item) - { - addNewItem(item, false); - ++nadded; - } - } + // form a list to add + uuid_vec_t::iterator it = mAddedItems.begin(); + pairs_list_t panel_list; + while(mAddedItems.size() > 0 && nadded < ADD_LIMIT) + { + LLViewerInventoryItem* item = gInventory.getItem(*it); + llassert(item); + if (item) + { + LLPanel *list_item = createNewItem(item); + if (list_item) + { + item_pair_t* new_pair = new item_pair_t(list_item, item->getUUID()); + panel_list.push_back(new_pair); + ++nadded; + } + } - it = removed_items.begin(); - for( ; removed_items.end() != it; ++it) - { - // don't filter items right away - removeItemByUUID(*it, false); - } + it = mAddedItems.erase(it); + } - // Filter, rearrange and notify parent about shape changes - filterItems(); + // add the list + // Note: usually item pairs are sorted with std::sort, but we are calling + // this function on idle and pairs' list can take a lot of time to sort + // through, so we are sorting items into list while adding them + addItemPairs(panel_list, false); - bool needs_refresh = add_limit_exceeded; - setNeedsRefresh(needs_refresh); - setForceRefresh(needs_refresh); + // update visibility of items in the list + std::string cur_filter = getFilterSubString(); + LLStringUtil::toUpper(cur_filter); + LLSD action; + action.with("match_filter", cur_filter); - // After list building completed, select items that had been requested to select before list was build - if(!needs_refresh) - { - updateSelection(); - } + pairs_const_iterator_t pair_it = panel_list.begin(); + for (; pair_it != panel_list.end(); ++pair_it) + { + item_pair_t* item_pair = *pair_it; + if (item_pair->first->getParent() != NULL) + { + updateItemVisibility(item_pair->first, action); + } + } + + rearrangeItems(); + notifyParentItemsRectChanged(); + + if (mAddedItems.size() > 0) + { + mRefreshState = REFRESH_LIST_APPEND; + } + else + { + // Note: while we do sort and check visibility at REFRESH_LIST_APPEND, update + // could have changed something about existing items so redo checks for all items. + mRefreshState = REFRESH_LIST_SORT; + } + break; + } + case REFRESH_LIST_SORT: + { + // Filter, sort, rearrange and notify parent about shape changes + filterItems(); + + if (mAddedItems.size() == 0) + { + // After list building completed, select items that had been requested to select before list was build + updateSelection(); + mRefreshState = REFRESH_COMPLETE; + } + else + { + mRefreshState = REFRESH_LIST_APPEND; + } + break; + } + default: + break; + } + + setForceRefresh(mRefreshState != REFRESH_COMPLETE); } void LLInventoryItemsList::computeDifference( @@ -204,24 +280,15 @@ void LLInventoryItemsList::computeDifference( LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved); } -void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/) +LLPanel* LLInventoryItemsList::createNewItem(LLViewerInventoryItem* item) { - if (!item) - { - LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; - llassert(item != NULL); - } - - LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item); - if (!list_item) - return; - - bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange); - if (!is_item_added) - { - LL_WARNS() << "Couldn't add flat list item." << LL_ENDL; - llassert(is_item_added); - } + if (!item) + { + LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; + llassert(item != NULL); + return NULL; + } + return LLPanelInventoryListItemBase::create(item); } // EOF diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 1aa230df99..fe05c2ed7c 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -51,9 +51,9 @@ public: /** * Let list know items need to be refreshed in next doIdle() */ - void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; } + void setNeedsRefresh(bool needs_refresh){ mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; } - bool getNeedsRefresh(){ return mNeedsRefresh; } + U32 getNeedsRefresh(){ return mRefreshState; } /** * Sets the flag indicating that the list needs to be refreshed even if it is @@ -71,7 +71,7 @@ public: * This is needed for example to filter items of the list hidden by closed * accordion tab. */ - void doIdle(); // Real idle routine + virtual void doIdle(); // Real idle routine static void idle(void* user_data); // static glue to doIdle() protected: @@ -94,17 +94,29 @@ protected: void computeDifference(const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved); /** - * Add an item to the list - */ - virtual void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); + * Create panel(item) from inventory item + */ + virtual LLPanel* createNewItem(LLViewerInventoryItem* item); + +protected: + enum ERefreshStates + { + REFRESH_COMPLETE = 0, + REFRESH_LIST_SORT, + REFRESH_LIST_APPEND, + REFRESH_LIST_ERASE, + REFRESH_ALL + }; + + ERefreshStates mRefreshState; private: uuid_vec_t mIDs; // IDs of items that were added in refreshList(). // Will be used in refresh() to determine added and removed ids uuid_vec_t mSelectTheseIDs; // IDs that will be selected if list is not loaded till now - - bool mNeedsRefresh; + uuid_vec_t mAddedItems; + uuid_vec_t mRemovedItems; bool mForceRefresh; diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index b8ea815797..efb6dc767d 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 6095781a11..b866142aaf 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -146,21 +146,9 @@ void append_to_last_message(std::list& messages, const std::string& line) class LLLogChatTimeScanner: public LLSingleton { + LLSINGLETON(LLLogChatTimeScanner); + 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))); - - // Seconds in timestamps - mDateSecStream.imbue(std::locale(mDateSecStream.getloc(), new date_input_facet(DATE_FORMAT_SEC))); - mTimeSecStream.imbue(std::locale(mTimeSecStream.getloc(), new time_facet(TIME_FORMAT_SEC))); - mTimeSecStream.imbue(std::locale(mTimeSecStream.getloc(), new time_input_facet(DATE_FORMAT_SEC))); - // - } - date getTodayPacificDate() { typedef boost::date_time::local_adjustor pst; @@ -276,6 +264,21 @@ private: // }; +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))); + + // Seconds in timestamps + mDateSecStream.imbue(std::locale(mDateSecStream.getloc(), new date_input_facet(DATE_FORMAT_SEC))); + mTimeSecStream.imbue(std::locale(mTimeSecStream.getloc(), new time_facet(TIME_FORMAT_SEC))); + mTimeSecStream.imbue(std::locale(mTimeSecStream.getloc(), new time_input_facet(DATE_FORMAT_SEC))); + // +} + 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 515b4027c8..5fe99af00b 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 7a713001d0..8c0e6da66e 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 1bfbe5ba1a..9138b94354 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.cpp b/indra/newview/llmutelist.cpp index 6dc148402b..e6a2d4ab66 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -47,6 +47,7 @@ #include "pipeline.h" #include +#include #include "lldispatcher.h" #include "llxfermanager.h" @@ -56,6 +57,7 @@ #include "llworld.h" //for particle system banning #include "llimview.h" #include "llnotifications.h" +#include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "lltrans.h" @@ -149,22 +151,6 @@ std::string LLMute::getDisplayType() const } } - -/* static */ -LLMuteList* LLMuteList::getInstance() -{ - // Register callbacks at the first time that we find that the message system has been created. - static BOOL registered = FALSE; - if( !registered && gMessageSystem != NULL) - { - registered = TRUE; - // Register our various callbacks - gMessageSystem->setHandlerFuncFast(_PREHASH_MuteListUpdate, processMuteListUpdate); - gMessageSystem->setHandlerFuncFast(_PREHASH_UseCachedMuteList, processUseCachedMuteList); - } - return LLSingleton::getInstance(); // Call the "base" implementation. -} - //----------------------------------------------------------------------------- // LLMuteList() //----------------------------------------------------------------------------- @@ -172,6 +158,18 @@ LLMuteList::LLMuteList() : mIsLoaded(FALSE) { gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList); + + // Register our callbacks. We may be constructed before gMessageSystem, so + // use callWhenReady() to register them as soon as gMessageSystem becomes + // available. + // When using bind(), must be explicit about default arguments such as + // that last NULL. + gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1, + _PREHASH_MuteListUpdate, processMuteListUpdate, + static_cast(NULL))); + gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1, + _PREHASH_UseCachedMuteList, processUseCachedMuteList, + static_cast(NULL))); } //----------------------------------------------------------------------------- @@ -234,6 +232,16 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) return FALSE; } + S32 mute_list_limit = gSavedSettings.getS32("MuteListLimit"); + if (getMutes().size() >= mute_list_limit) + { + LL_WARNS() << "Mute limit is reached; ignored" << LL_ENDL; + LLSD args; + args["MUTE_LIMIT"] = mute_list_limit; + LLNotifications::instance().add(LLNotification::Params("MuteLimitReached").substitutions(args)); + return FALSE; + } + if (mute.mType == LLMute::BY_NAME) { // Can't mute empty string by name diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 4e7b6ee880..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,13 +83,6 @@ public: AR_COUNT // enum count }; - LLMuteList(); - ~LLMuteList(); - - // Implemented locally so that we can perform some delayed initialization. - // Callers should be careful to call this one and not LLSingleton::getInstance() - // which would circumvent that mechanism. -MG - static LLMuteList* getInstance(); void addObserver(LLMuteListObserver* observer); void removeObserver(LLMuteListObserver* observer); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h old mode 100644 new mode 100755 index b40fcfb922..603433378a --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -32,6 +32,7 @@ // #include "llbutton.h" #include "lllayoutstack.h" +#include "llinitdestroyclass.h" class LLLocationInputCtrl; class LLMenuGL; @@ -89,12 +90,12 @@ class LLNavigationBar : public LLSingleton // { + LLSINGLETON(LLNavigationBar); + virtual ~LLNavigationBar(); LOG_CLASS(LLNavigationBar); friend class LLDestroyClass; - + public: - LLNavigationBar(); - virtual ~LLNavigationBar(); // Make navigation bar part of the UI // /*virtual*/ void draw(); diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index 5917d089ca..fc74eb7da8 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/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 404fc7d3cc..365c621d5f 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -106,11 +106,8 @@ BOOL LLOutfitGallery::postBuild() { BOOL rv = LLOutfitListBase::postBuild(); mScrollPanel = getChild("gallery_scroll_panel"); - // Don't parse XML to create a LLPanel manually - //mGalleryPanel = getChild("gallery_panel"); - LLPanel::Params params = LLPanel::getDefaultParams(); + LLPanel::Params params = LLPanel::getDefaultParams(); // Don't parse XML when creating dummy LLPanel mGalleryPanel = LLUICtrlFactory::create(params); - // mMessageTextBox = getChild("no_outfits_txt"); mOutfitGalleryMenu = new LLOutfitGalleryContextMenu(this); return rv; @@ -680,7 +677,6 @@ BOOL LLOutfitGalleryItem::postBuild() mOutfitNameText = getChild("outfit_name"); mOutfitWornText = getChild("outfit_worn_text"); - //mFotoBgPanel = getChild("foto_bg_panel"); // Does not exist mTextBgPanel = getChild("text_bg_panel"); setOutfitWorn(false); mHidden = false; @@ -799,7 +795,7 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu() LLMenuItemCallGL* upload_item = menu->findChild("upload_photo"); if (upload_item) { - upload_item->setLabelArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + upload_item->setLabelArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); } return menu; // @@ -1142,7 +1138,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id) return; } - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). void *nruserdata = NULL; nruserdata = (void *)&outfit_id; diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index 79ac78c42e..b9fc10f015 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -275,7 +275,6 @@ private: LLTextBox* mOutfitNameText; LLTextBox* mOutfitWornText; LLPanel* mTextBgPanel; - //LLPanel* mFotoBgPanel; // Does not exist bool mSelected; bool mWorn; bool mDefaultImage; 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/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 66ff8a2101..400f18b3ab 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -1211,7 +1211,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist) LLMenuItemCallGL* upload_item = mMenu->findChild("upload_photo"); if (upload_item) { - upload_item->setLabelArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + upload_item->setLabelArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); } // } diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index dd2749e1e4..aee99a39d2 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -120,8 +120,7 @@ class LLEditWearableDictionary : public LLSingleton //-------------------------------------------------------------------- // Constructors and Destructors //-------------------------------------------------------------------- -public: - LLEditWearableDictionary(); + LLSINGLETON(LLEditWearableDictionary); virtual ~LLEditWearableDictionary(); //-------------------------------------------------------------------- diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 89361b5707..38f2016514 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -415,7 +415,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) // FIRE-7091 group creation cost inaccurate on opensim> //LLNotificationsUtil::add("CreateGroupCost", LLSD(), LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2)); LLSD args; - S32 cost = LLGlobalEconomy::Singleton::getInstance()->getPriceGroupCreate(); + S32 cost = LLGlobalEconomy::getInstance()->getPriceGroupCreate(); args["[COST]"] = llformat("%d", cost); LLNotificationsUtil::add("CreateGroupCost", args, LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2)); // FIRE-7091 group creation cost inaccurate on opensim> diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 52cd1354d0..100749516b 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -308,7 +308,7 @@ BOOL LLPanelMainInventory::postBuild() // // // *TODO:Get the cost info from the server // const std::string upload_cost("10"); - S32 cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 cost = LLGlobalEconomy::getInstance()->getPriceUpload(); std::string upload_cost; #ifdef OPENSIM if (LLGridManager::getInstance()->isInOpenSim()) @@ -1820,7 +1820,7 @@ void LLPanelMainInventory::setUploadCostIfNeeded() LLMenuItemBranchGL* upload_menu = menu->findChild("upload"); if(upload_menu) { - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); std::string cost_str; // getPriceUpload() returns -1 if no data available yet. diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index d02067fd4d..a5bc45a711 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -794,6 +794,10 @@ void LLPanelOutfitEdit::onVisibilityChanged(const LLSD &in_visible_chain) { update(); } + else + { + mWearableListManager->holdProgress(); //list population restarts with visibility + } } void LLPanelOutfitEdit::onAddWearableClicked(void) diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index 95e8c88914..45e4318f4c 100644 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -150,14 +150,14 @@ BOOL LLPanelSnapshotInventory::postBuild() // virtual void LLPanelSnapshotInventory::onOpen(const LLSD& key) { - getChild("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + getChild("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); // FIRE-10537 - Temp texture uploads aren't functional on SSB regions - if (LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() == 0 + if (LLGlobalEconomy::getInstance()->getPriceUpload() == 0 || gAgent.getRegion()->getCentralBakeVersion() > 0) { gSavedSettings.setBOOL("TemporaryUpload", FALSE); } - getChild("inventory_temp_upload")->setVisible(LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() > 0 && gAgent.getRegion()->getCentralBakeVersion() == 0); + getChild("inventory_temp_upload")->setVisible(LLGlobalEconomy::getInstance()->getPriceUpload() > 0 && gAgent.getRegion()->getCentralBakeVersion() == 0); // LLPanelSnapshot::onOpen(key); } @@ -187,7 +187,7 @@ LLPanelSnapshotInventory::~LLPanelSnapshotInventory() void LLPanelSnapshotInventoryBase::onSend() { - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); if (can_afford_transaction(expected_upload_cost)) { if (mSnapshotFloater) @@ -223,7 +223,7 @@ BOOL LLPanelOutfitSnapshotInventory::postBuild() // virtual void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key) { - getChild("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload())); + getChild("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload())); LLPanelSnapshot::onOpen(key); } diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 269f16c5e4..95c14e4226 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -77,12 +77,12 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions() mCommitCallbackRegistrar.add("Snapshot.SendToFacebook", boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this)); mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this)); mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this)); - LLGlobalEconomy::Singleton::getInstance()->addObserver(this); + LLGlobalEconomy::getInstance()->addObserver(this); } LLPanelSnapshotOptions::~LLPanelSnapshotOptions() { - LLGlobalEconomy::Singleton::getInstance()->removeObserver(this); + LLGlobalEconomy::getInstance()->removeObserver(this); } // virtual @@ -100,7 +100,7 @@ void LLPanelSnapshotOptions::onOpen(const LLSD& key) void LLPanelSnapshotOptions::updateUploadCost() { - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); getChild("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost)); } diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index f8ff2735d7..e45ca2dfc2 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -122,7 +122,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 b6d2cd94df..5405548ea8 100644 --- a/indra/newview/llpaneltopinfobar.h +++ b/indra/newview/llpaneltopinfobar.h @@ -28,6 +28,7 @@ #define LLPANELTOPINFOBAR_H_ #include "llpanel.h" +#include "llinitdestroyclass.h" class LLButton; class LLTextBox; @@ -36,6 +37,8 @@ class LLParcelChangeObserver; class LLPanelTopInfoBar : public LLPanel, public LLSingleton, private LLDestroyClass { + LLSINGLETON(LLPanelTopInfoBar); + ~LLPanelTopInfoBar(); LOG_CLASS(LLPanelTopInfoBar); friend class LLDestroyClass; @@ -43,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 7eb8cc68ef..73a2774f2d 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 4001f95a81..68cda42ec2 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 c4de2cb6a6..dcfc28b5bd 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) { mDuringBulkUpdate = false; // diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index 74494fbad3..8530f5100a 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.cpp b/indra/newview/llpresetsmanager.cpp index 3c5c258ce7..3333a83a86 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -64,6 +64,10 @@ void LLPresetsManager::triggerChangeSignal() void LLPresetsManager::createMissingDefault() { // FIRE-19810: Make presets global since PresetGraphicActive setting is global as well + //if(gDirUtilp->getLindenUserDir().empty()) + //{ + // return; + //} //std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml"); std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml"); // diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h index aca7ed2dd2..1d9b27ec1d 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; // Graphic preset controls independent from XUI 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 311cb59c60..fcfd5ccc64 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 4ea071d910..ecd82639d8 100644 --- a/indra/newview/llscriptfloater.h +++ b/indra/newview/llscriptfloater.h @@ -41,6 +41,9 @@ class LLScriptFloaterManager : public LLSingleton // *TODO // LLScriptFloaterManager and LLScriptFloater will need some refactoring after we // know how script notifications should look like. + // script dialogs position + //LLSINGLETON_EMPTY_CTOR(LLScriptFloaterManager); + LLSINGLETON(LLScriptFloaterManager); public: typedef enum e_object_type @@ -125,10 +128,6 @@ private: floater_position_map_t mFloaterPositions; // script dialogs position -private: - LLScriptFloaterManager(); - friend class LLSingleton; - public: S32 mNavigationPanelPad; S32 mFavoritesPanelPad; diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h index 7fe2aa2737..4ae6122396 100644 --- a/indra/newview/llsearchhistory.h +++ b/indra/newview/llsearchhistory.h @@ -28,6 +28,7 @@ #define LL_LLSEARCHHISTORY_H #include "llsingleton.h" +#include "llinitdestroyclass.h" #include "llui.h" /** @@ -36,6 +37,7 @@ */ class LLSearchHistory : public LLSingleton, private LLDestroyClass { + LLSINGLETON(LLSearchHistory); friend class LLDestroyClass; public: @@ -71,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 9658044491..7e0e60e05f 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -456,6 +456,9 @@ namespace nd class LLSelectMgr : public LLEditMenuHandler, public LLSingleton, public nd::selection::PropertiesServer { + 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? @@ -481,9 +484,6 @@ public: LLCachedControl mDebugSelectMgr; public: - LLSelectMgr(); - ~LLSelectMgr(); - static void cleanupGlobals(); // LLEditMenuHandler interface diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 51de8b4318..c3c00361e3 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -1071,7 +1071,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name) LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL); std::string who_took_it; LLAgentUI::buildFullname(who_took_it); - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string; std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string; LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY; 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/llstartup.cpp b/indra/newview/llstartup.cpp index 1d7db4e733..b580c437a4 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -201,6 +201,7 @@ #include "llstartuplistener.h" #include "lltoolbarview.h" #include "llexperiencelog.h" +#include "llcleanup.h" #include "llstacktrace.h" @@ -3651,7 +3652,7 @@ void LLStartUp::initExperiences() void LLStartUp::cleanupNameCache() { - LLAvatarNameCache::cleanupClass(); + SUBSYSTEM_CLEANUP(LLAvatarNameCache); delete gCacheName; gCacheName = NULL; 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 3551622193..caddba5527 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; @@ -68,7 +68,6 @@ private: bool mInitialized; public: - LLSyntaxIdLSL(); void initialize(); bool keywordFetchInProgress(); LLSD getKeywordsXML() const { return mKeywordsXml; }; diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 1f00b94e65..92cd5348c4 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -32,6 +32,7 @@ #include "llscreenchannel.h" #include "llsyswellitem.h" #include "lltransientdockablefloater.h" +#include "llinitdestroyclass.h" // Firestorm includes #include "llbutton.h" diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h index 401c340362..6687527910 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 f0131ac897..c646bb7edf 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 306ecc21d0..a405754914 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -701,7 +701,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 6f91369e65..d27f7b7b57 100644 --- a/indra/newview/lltoolcomp.h +++ b/indra/newview/lltoolcomp.h @@ -106,9 +106,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); @@ -131,9 +131,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); @@ -152,9 +152,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); @@ -179,9 +179,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); @@ -202,9 +202,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); @@ -222,14 +222,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); @@ -248,7 +248,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 116fd38c3f..430ba9c8d0 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 4521680441..4c6265f33d 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 82844ed6e1..f13263b417 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -72,7 +72,7 @@ extern BOOL gDebugClicks; // // Methods // -LLToolGrab::LLToolGrab( LLToolComposite* composite ) +LLToolGrabBase::LLToolGrabBase( LLToolComposite* composite ) : LLTool( std::string("Grab"), composite ), mMode( GRAB_INACTIVE ), mVerticalDragging( FALSE ), @@ -91,12 +91,12 @@ LLToolGrab::LLToolGrab( LLToolComposite* composite ) mHideBuildHighlight(FALSE) { } -LLToolGrab::~LLToolGrab() +LLToolGrabBase::~LLToolGrabBase() { } // virtual -void LLToolGrab::handleSelect() +void LLToolGrabBase::handleSelect() { if(gFloaterTools) { @@ -109,7 +109,7 @@ void LLToolGrab::handleSelect() gGrabBtnSpin = FALSE; } -void LLToolGrab::handleDeselect() +void LLToolGrabBase::handleDeselect() { if( hasMouseCapture() ) { @@ -126,7 +126,7 @@ void LLToolGrab::handleDeselect() } -BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask) +BOOL LLToolGrabBase::handleDoubleClick(S32 x, S32 y, MASK mask) { if (gDebugClicks) { @@ -136,7 +136,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) { @@ -158,7 +158,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(); @@ -192,7 +192,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(); @@ -325,7 +325,7 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) } -void LLToolGrab::startSpin() +void LLToolGrabBase::startSpin() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -349,7 +349,7 @@ void LLToolGrab::startSpin() } -void LLToolGrab::stopSpin() +void LLToolGrabBase::stopSpin() { mSpinGrabbing = FALSE; @@ -383,7 +383,7 @@ void LLToolGrab::stopSpin() } -void LLToolGrab::startGrab() +void LLToolGrabBase::startGrab() { // Compute grab_offset in the OBJECT's root's coordinate frame // (sometimes root == object) @@ -432,7 +432,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()) { @@ -491,7 +491,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; @@ -754,7 +754,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; @@ -911,7 +911,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; @@ -919,7 +919,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 ) { @@ -960,7 +960,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); @@ -997,7 +997,7 @@ BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } -void LLToolGrab::stopEditing() +void LLToolGrabBase::stopEditing() { if( hasMouseCapture() ) { @@ -1005,7 +1005,7 @@ void LLToolGrab::stopEditing() } } -void LLToolGrab::onMouseCaptureLost() +void LLToolGrabBase::onMouseCaptureLost() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -1062,7 +1062,7 @@ void LLToolGrab::onMouseCaptureLost() } -void LLToolGrab::stopGrab() +void LLToolGrabBase::stopGrab() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) @@ -1103,29 +1103,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 5a64723b33..d5ec645949 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 0e3b82c81b..764b325909 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/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index b09262fdf0..43cc07b187 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -177,7 +177,7 @@ S32 LLResourceUploadInfo::getEconomyUploadCost() getAssetType() == LLAssetType::AT_ANIMATION || getAssetType() == LLAssetType::AT_MESH) { - return LLGlobalEconomy::Singleton::instance().getPriceUpload(); + return LLGlobalEconomy::instance().getPriceUpload(); } return 0; 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 2f7aff176c..9a8d51f894 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 8fc3ef329a..72b3743681 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 44925e3aca..2b0e9bbbb6 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -97,107 +97,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. * @@ -220,6 +123,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 @@ -1443,24 +1443,18 @@ void update_inventory_item( if (updates.has("asset_id")) { updates.erase("asset_id"); - // Check for non-null UUID as in LLViewerInventoryItem::updateServer - //updates["hash_id"] = update_item->getTransactionID(); - if(update_item->getTransactionID().notNull()) + if (update_item->getTransactionID().notNull()) { updates["hash_id"] = update_item->getTransactionID(); } - // } if (updates.has("shadow_id")) { updates.erase("shadow_id"); - // Check for non-null UUID as in LLViewerInventoryItem::updateServer - //updates["hash_id"] = update_item->getTransactionID(); - if(update_item->getTransactionID().notNull()) + if (update_item->getTransactionID().notNull()) { updates["hash_id"] = update_item->getTransactionID(); } - // } AISAPI::completion_t cr = boost::bind(&doInventoryCb, cb, _1); AISAPI::UpdateItem(item_id, updates, cr); diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 358d566ffa..3744f3096d 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -30,7 +30,7 @@ #include "llinventory.h" #include "llframetimer.h" #include "llwearable.h" -#include "llui.h" //for LLDestroyClass +#include "llinitdestroyclass.h" //for LLDestroyClass #include // boost::signals2::trackable 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 fd93d4b140..0f2e563f18 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -63,6 +63,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/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 8109b0ae88..b0294829af 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -167,6 +167,7 @@ static bool sForceUpdate = false; static LLUUID sOnlyAudibleTextureID = LLUUID::null; static F64 sLowestLoadableImplInterest = 0.0f; static bool sAnyMediaShowing = false; +static bool sAnyMediaPlaying = false; static boost::signals2::connection sTeleportFinishConnection; static std::string sUpdatedCookies; static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt"; @@ -610,6 +611,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) createSpareBrowserMediaSource(); sAnyMediaShowing = false; + sAnyMediaPlaying = false; sUpdatedCookies = getCookieStore()->getChangedCookies(); if(!sUpdatedCookies.empty()) { @@ -828,6 +830,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg) sAnyMediaShowing = true; } + if (!pimpl->getUsedInUI() && pimpl->hasMedia() && (!pimpl->isMediaPaused() || !pimpl->isMediaTimeBased())) + { + sAnyMediaPlaying = true; + } + } } @@ -880,6 +887,13 @@ bool LLViewerMedia::isAnyMediaShowing() return sAnyMediaShowing; } +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isAnyMediaPlaying() +{ + return sAnyMediaPlaying; +} + ////////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerMedia::setAllMediaEnabled(bool val) @@ -939,6 +953,78 @@ void LLViewerMedia::setAllMediaEnabled(bool val) } } +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setAllMediaPaused(bool val) +{ + // Set "tentative" autoplay first. We need to do this here or else + // re-enabling won't start up the media below. + gSavedSettings.setBOOL("MediaTentativeAutoPlay", val); + + // Then + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for (; iter != end; iter++) + { + LLViewerMediaImpl* pimpl = *iter; + if (!pimpl->getUsedInUI()) + { + // upause/pause time based media, enable/disable any other + if (!val) + { + pimpl->setDisabled(val); + if (pimpl->isMediaTimeBased() && pimpl->isMediaPaused()) + { + pimpl->play(); + return; + } + } + else if (pimpl->isMediaTimeBased() && pimpl->mMediaSource) + { + pimpl->pause(); + } + else + { + pimpl->setDisabled(val); + } + } + } + + // Also do Parcel Media and Parcel Audio + if (!val) + { + if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia()) + { + LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + } + + if (gSavedSettings.getBOOL("AudioStreamingMusic") && + !LLViewerMedia::isParcelAudioPlaying() && + gAudiop && + LLViewerMedia::hasParcelAudio()) + { + if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) + { + // 'false' means unpause + gAudiop->pauseInternetStream(false); + } + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + } + } + } + else { + // This actually unloads the impl, as opposed to "stop"ping the media + LLViewerParcelMedia::stop(); + if (gAudiop) + { + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); + } + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // static bool LLViewerMedia::isParcelMediaPlaying() diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 1fecf15fc9..5c876861c4 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -105,9 +105,12 @@ public: // Is any media currently "showing"? Includes Parcel Media. Does not include media in the UI. static bool isAnyMediaShowing(); + static bool isAnyMediaPlaying(); // Set all media enabled or disabled, depending on val. Does not include media in the UI. static void setAllMediaEnabled(bool val); - + // Set all media paused or playing, depending on val. Does not include media in the UI. + static void setAllMediaPaused(bool val); + static void updateMedia(void* dummy_arg = NULL); static void initClass(); 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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8f942db621..1e4ae74956 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -139,6 +139,7 @@ #include "llpathfindingmanager.h" #include "llstartup.h" #include "boost/unordered_map.hpp" +#include "llcleanup.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvactions.h" #include "rlvhandler.h" @@ -635,7 +636,7 @@ void init_menus() // // *TODO:Also fix cost in llfolderview.cpp for Inventory menus // const std::string upload_cost("10"); // \0/ Copypasta! See llviewermessage, llviewermenu and llpanelmaininventory - S32 cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 cost = LLGlobalEconomy::getInstance()->getPriceUpload(); std::string upload_cost; #ifdef OPENSIM if (LLGridManager::getInstance()->isInOpenSim()) @@ -10687,7 +10688,7 @@ class LLWorldPostProcess : public view_listener_t void handle_flush_name_caches() { // Crash fix - //LLAvatarNameCache::cleanupClass(); + //SUBSYSTEM_CLEANUP(LLAvatarNameCache); LLAvatarNameCache::clearCache(); // if (gCacheName) gCacheName->clear(); @@ -10737,7 +10738,7 @@ class LLToggleUIHints : public view_listener_t void LLUploadCostCalculator::calculateCost() { - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // getPriceUpload() returns -1 if no data available yet. // diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 040b409d0c..9f58e4cef7 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -88,7 +88,7 @@ class LLFileEnableUpload : public view_listener_t bool handleEvent(const LLSD& userdata) { return true; -// bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); +// bool new_value = gStatusBar && LLGlobalEconomy::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::getInstance()->getPriceUpload()); // return new_value; } }; @@ -97,6 +97,12 @@ class LLFileEnableUploadModel : public view_listener_t { bool handleEvent(const LLSD& userdata) { + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::findInstance("upload_model"); + if (fmp && fmp->isModelLoading()) + { + return false; + } + return true; } }; @@ -569,7 +575,7 @@ class LLFileUploadModel : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::getInstance("upload_model"); - if (fmp) + if (fmp && !fmp->isModelLoading()) { fmp->loadModel(3); } @@ -620,38 +626,6 @@ class LLFileUploadAnim : public view_listener_t } }; -// Threaded file pickers -void upload_bulk_callback(std::list filenames) -{ - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); - - for (std::list::iterator it = filenames.begin(); it != filenames.end(); ++it) - { - std::string filename = *it; - - std::string name = gDirUtilp->getBaseFileName(filename, true); - - std::string asset_name = name; - LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); - LLStringUtil::replaceChar(asset_name, '|', '?'); - LLStringUtil::stripNonprintable(asset_name); - LLStringUtil::trim(asset_name); - - LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( - filename, - asset_name, - asset_name, 0, - LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); - - upload_new_resource(uploadInfo, NULL, NULL); - } -} -// - class LLFileUploadBulk : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -670,44 +644,41 @@ class LLFileUploadBulk : public view_listener_t // // Also fix single upload to charge first, then refund - // Threaded filepickers - //LLFilePicker& picker = LLFilePicker::instance(); - //if (picker.getMultipleOpenFiles()) - //{ - // std::string filename = picker.getFirstFile(); - // S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getMultipleOpenFiles()) + { + std::string filename = picker.getFirstFile(); + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); - // while (!filename.empty()) - // { - // std::string name = gDirUtilp->getBaseFileName(filename, true); + while (!filename.empty()) + { + std::string name = gDirUtilp->getBaseFileName(filename, true); - // std::string asset_name = name; - // LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); - // LLStringUtil::replaceChar(asset_name, '|', '?'); - // LLStringUtil::stripNonprintable(asset_name); - // LLStringUtil::trim(asset_name); + std::string asset_name = name; + LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); + LLStringUtil::replaceChar(asset_name, '|', '?'); + LLStringUtil::stripNonprintable(asset_name); + LLStringUtil::trim(asset_name); - // LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( - // filename, - // asset_name, - // asset_name, 0, - // LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - // LLFloaterPerms::getNextOwnerPerms("Uploads"), - // LLFloaterPerms::getGroupPerms("Uploads"), - // LLFloaterPerms::getEveryonePerms("Uploads"), - // expected_upload_cost)); + LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + filename, + asset_name, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost)); - // upload_new_resource(uploadInfo, NULL, NULL); + upload_new_resource(uploadInfo, NULL, NULL); - // filename = picker.getNextFile(); - // } - //} - //else - //{ - // LL_INFOS() << "Couldn't import objects from file" << LL_ENDL; - //} - // - LLGenericLoadMultipleFilePicker::open(LLFilePicker::FFLOAD_ALL, boost::bind(&upload_bulk_callback, _1)); + filename = picker.getNextFile(); + } + } + else + { + LL_INFOS() << "Couldn't import objects from file" << LL_ENDL; + } return true; } }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 92089e2e9c..781fedfbf2 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6999,15 +6999,12 @@ static std::string reason_from_transaction_type(S32 transaction_type, case TRANS_CLASSIFIED_CHARGE: return LLTrans::getString("to publish a classified ad"); - // FIRE-16827: Display custom payment message case TRANS_GIFT: // Simulator returns "Payment" if no custom description has been entered return (item_desc == "Payment" ? std::string() : item_desc); - // // These have no reason to display, but are expected and should not // generate warnings - //case TRANS_GIFT: // FIRE-16827: Display custom payment message case TRANS_PAY_OBJECT: case TRANS_OBJECT_PAYS: return std::string(); @@ -7156,7 +7153,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) LLSD payload; bool you_paid_someone = (source_id == gAgentID); - std::string gift_suffix = (transaction_type == TRANS_GIFT ? "_gift" : ""); // FIRE-16827: Display custom payment message + std::string gift_suffix = (transaction_type == TRANS_GIFT ? "_gift" : ""); if (you_paid_someone) { if(!gSavedSettings.getBOOL("NotifyMoneySpend")) @@ -7170,8 +7167,8 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) { if (dest_id.notNull()) { - message = success ? LLTrans::getString("you_paid_ldollars" + gift_suffix, args) : // FIRE-16827: Display custom payment message - LLTrans::getString("you_paid_failure_ldollars", args); + message = success ? LLTrans::getString("you_paid_ldollars" + gift_suffix, args) : + LLTrans::getString("you_paid_failure_ldollars" + gift_suffix, args); } else { @@ -7209,7 +7206,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) if (dest_id.notNull()) { message = success ? LLTrans::getString("you_paid_ldollars" + gift_suffix, args) : - LLTrans::getString("you_paid_failure_ldollars", args); + LLTrans::getString("you_paid_failure_ldollars" + gift_suffix, args); } else { @@ -7241,7 +7238,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) if (dest_id.notNull()) { message_notification_well = success ? LLTrans::getString("you_paid_ldollars" + gift_suffix, args) : - LLTrans::getString("you_paid_failure_ldollars", args); + LLTrans::getString("you_paid_failure_ldollars" + gift_suffix, args); } else { @@ -7277,9 +7274,9 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) name_id = source_id; if (!reason.empty()) { - message = LLTrans::getString("paid_you_ldollars" + gift_suffix, args); // FIRE-16827: Display custom payment message + message = LLTrans::getString("paid_you_ldollars" + gift_suffix, args); } - else + else { message = LLTrans::getString("paid_you_ldollars_no_reason", args); } @@ -8177,8 +8174,8 @@ void process_frozen_message(LLMessageSystem *msgsystem, void **user_data) // do some extra stuff once we get our economy data void process_economy_data(LLMessageSystem *msg, void** /*user_data*/) { - LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance()); - S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::getInstance()); + S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // // AW: from this point anything is bogus because it's all replaced by the LLUploadCostCalculator in llviewermenu // LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL; diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index d0df38c948..0c9ea66a43 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -226,6 +226,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 8df3e606b8..a4a8bd113b 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -95,13 +95,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/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index bc910db465..081e604793 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -102,6 +102,7 @@ #include "llmediaentry.h" #include "llfloaterperms.h" #include "llvocache.h" +#include "llcleanup.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvactions.h" #include "rlvcommon.h" @@ -548,11 +549,11 @@ void LLViewerObject::initVOClasses() void LLViewerObject::cleanupVOClasses() { - LLVOGrass::cleanupClass(); - LLVOWater::cleanupClass(); - LLVOTree::cleanupClass(); - LLVOAvatar::cleanupClass(); - LLVOVolume::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVOGrass); + SUBSYSTEM_CLEANUP(LLVOWater); + SUBSYSTEM_CLEANUP(LLVOTree); + SUBSYSTEM_CLEANUP(LLVOAvatar); + SUBSYSTEM_CLEANUP(LLVOVolume); sObjectDataMap.clear(); } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index dccb8d1925..9f66d1807c 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(); - // Aurora Sim void init(F32 region_size); // Aurora Sim 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 027e9bbd5e..e6a01c2e3b 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -251,14 +251,12 @@ extern LLTrace::EventStatHandle > OBJECT_CACHE_HIT class LLViewerStats : public LLSingleton { + LLSINGLETON(LLViewerStats); + ~LLViewerStats(); + public: void resetStats(); -public: - - LLViewerStats(); - ~LLViewerStats(); - void updateFrameStats(const F64Seconds time_diff); void addToMessage(LLSD &body); 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 c7657c8121..5bf2a293fd 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -242,6 +242,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 870fbdd2fc..e3f4414c0c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -216,6 +216,7 @@ #include "llwindowlistener.h" #include "llviewerwindowlistener.h" #include "llpaneltopinfobar.h" +#include "llcleanup.h" #include "llimview.h" #include "llviewermenufile.h" @@ -314,13 +315,8 @@ public: class RecordToChatConsole : public LLSingleton { + LLSINGLETON(RecordToChatConsole); public: - RecordToChatConsole() - : LLSingleton(), - mRecorder(new RecordToChatConsoleRecorder()) - { - } - void startRecorder() { LLError::addRecorder(mRecorder); } void stopRecorder() { LLError::removeRecorder(mRecorder); } @@ -328,6 +324,11 @@ private: LLError::RecorderPtr mRecorder; }; +RecordToChatConsole::RecordToChatConsole(): + mRecorder(new RecordToChatConsoleRecorder()) +{ +} + //////////////////////////////////////////////////////////////////////////// // // LLDebugText @@ -2448,10 +2449,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 @@ -2487,7 +2485,7 @@ void LLViewerWindow::shutdownGL() // Shutdown GL cleanly. Order is very important here. //-------------------------------------------------------- LLFontGL::destroyDefaultFonts(); - LLFontManager::cleanupClass(); + SUBSYSTEM_CLEANUP(LLFontManager); stop_glerror(); gSky.cleanup(); @@ -2510,7 +2508,7 @@ void LLViewerWindow::shutdownGL() LLWorldMapView::cleanupTextures(); LLViewerTextureManager::cleanup() ; - LLImageGL::cleanupClass() ; + SUBSYSTEM_CLEANUP(LLImageGL) ; LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ; @@ -2528,7 +2526,7 @@ void LLViewerWindow::shutdownGL() exoPostProcess::deleteSingleton(); // Exodus vignette - LLVertexBuffer::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVertexBuffer); LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ; } 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 11291c1103..ae1d87a9f5 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -318,11 +318,11 @@ typedef enum e_voice_power_level 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; @@ -519,6 +519,8 @@ protected: **/ class LLSpeakerVolumeStorage : public LLSingleton { + LLSINGLETON(LLSpeakerVolumeStorage); + ~LLSpeakerVolumeStorage(); LOG_CLASS(LLSpeakerVolumeStorage); public: @@ -547,10 +549,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 b48da94084..7d43efc908 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 //@{ @@ -1043,10 +1042,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 7b20d4c21e..a77212c6fc 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -90,10 +90,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 408987b707..220a67b504 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; @@ -321,11 +323,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.cpp b/indra/newview/llwearableitemslist.cpp index 56fd8da024..09bb908b0b 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -684,24 +684,16 @@ LLWearableItemsList::~LLWearableItemsList() {} // virtual -void LLWearableItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/) +LLPanel* LLWearableItemsList::createNewItem(LLViewerInventoryItem* item) { - if (!item) - { - LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; - llassert(item != NULL); - } + if (!item) + { + LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL; + llassert(item != NULL); + return NULL; + } - LLPanelWearableOutfitItem *list_item = LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled); - if (!list_item) - return; - - bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange); - if (!is_item_added) - { - LL_WARNS() << "Couldn't add flat list item." << LL_ENDL; - llassert(is_item_added); - } + return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled); } void LLWearableItemsList::updateList(const LLUUID& category_id) diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 18a30f083b..f3182ed163 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: @@ -453,7 +453,7 @@ public: virtual ~LLWearableItemsList(); - /*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); + /*virtual*/ LLPanel* createNewItem(LLViewerInventoryItem* item); void updateList(const LLUUID& category_id); 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..90882cf04a 100644 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -34,6 +34,7 @@ class LLWinDebug: public LLSingleton { + LLSINGLETON_EMPTY_CTOR(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 f904ca72cd..3ac14dcb9e 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -119,6 +119,8 @@ struct WLFloatControl { /// WindLight parameter manager class - what controls all the wind light shaders class LLWLParamManager : public LLSingleton { + LLSINGLETON(LLWLParamManager); + ~LLWLParamManager(); LOG_CLASS(LLWLParamManager); public: @@ -291,11 +293,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 4bbe548c87..aff8e4aa45 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(); void refreshLimits();// diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 9aee81bb23..ce9b192c6b 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -216,10 +216,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**); diff --git a/indra/newview/piemenu.h b/indra/newview/piemenu.h index eacd872586..1efa77b278 100644 --- a/indra/newview/piemenu.h +++ b/indra/newview/piemenu.h @@ -35,7 +35,9 @@ const S32 PIE_MAX_SLICES = 8; // PieChildRegistry contains a list of allowed child types for the XUI definition struct PieChildRegistry : public LLChildRegistry -{}; +{ + LLSINGLETON_EMPTY_CTOR(PieChildRegistry); +}; class PieMenu : public LLMenuGL { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b6edf48714..dc878016da 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -114,6 +114,7 @@ #include "llpathfindingpathtool.h" #include "llscenemonitor.h" #include "llprogressview.h" +#include "llcleanup.h" // [RLVa:KB] - Checked: RLVa-2.0.0 #include "rlvactions.h" #include "rlvlocks.h" @@ -7479,7 +7480,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) } LLVOPartGroup::destroyGL(); - LLVertexBuffer::cleanupClass(); + SUBSYSTEM_CLEANUP(LLVertexBuffer); //delete all name pool caches LLGLNamePool::cleanupPools(); @@ -11725,10 +11726,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) avatar->setImpostorDim(tdim); - // FIRE-20333: Set back to correct value depending on sMaxNonImpostors - //LLVOAvatar::sUseImpostors = true; // @TODO ??? LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors); - // sUseOcclusion = occlusion; sReflectionRender = false; sImpostorRender = false; diff --git a/indra/newview/qtoolalign.h b/indra/newview/qtoolalign.h index 8ef28cf4c5..ab198bd429 100644 --- a/indra/newview/qtoolalign.h +++ b/indra/newview/qtoolalign.h @@ -16,10 +16,10 @@ class LLToolSelectRect; class QToolAlign : public LLTool, public LLSingleton { -public: - QToolAlign(); + LLSINGLETON(QToolAlign); virtual ~QToolAlign(); +public: virtual void handleSelect(); virtual void handleDeselect(); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/newview/rlvextensions.cpp b/indra/newview/rlvextensions.cpp index 43a5f61f50..9a3def7735 100644 --- a/indra/newview/rlvextensions.cpp +++ b/indra/newview/rlvextensions.cpp @@ -157,10 +157,9 @@ bool RlvWindLightControl::setFloat(F32 nValue) class RlvWindLight : public LLSingleton { - friend class LLSingleton; -public: - RlvWindLight(); + LLSINGLETON(RlvWindLight); +public: std::string getValue(const std::string& strSetting, bool& fError); bool setValue(const std::string& strRlvName, const std::string& strValue); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 964d8a5c57..e03fc7d586 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -90,10 +90,9 @@ protected: class RlvBehaviourDictionary : public LLSingleton { - friend class LLSingleton; friend class RlvFloaterBehaviours; -protected: - RlvBehaviourDictionary(); + + LLSINGLETON(RlvBehaviourDictionary); ~RlvBehaviourDictionary(); public: void addEntry(const RlvBehaviourInfo* pEntry); @@ -570,8 +569,7 @@ protected: class RlvForceWear : public LLSingleton { -protected: - RlvForceWear() {} + LLSINGLETON_EMPTY_CTOR(RlvForceWear); public: // Folders @@ -663,9 +661,6 @@ protected: typedef std::map pendingattachments_map_t; pendingattachments_map_t m_pendingAttachments; - -private: - friend class LLSingleton; }; // ============================================================================ @@ -674,9 +669,7 @@ private: class RlvBehaviourNotifyHandler : public LLSingleton { - friend class LLSingleton; -protected: - RlvBehaviourNotifyHandler(); + LLSINGLETON(RlvBehaviourNotifyHandler); virtual ~RlvBehaviourNotifyHandler() { if (m_ConnCommand.connected()) m_ConnCommand.disconnect(); } public: diff --git a/indra/newview/rlvinventory.h b/indra/newview/rlvinventory.h index 349715034d..2eb73380bf 100644 --- a/indra/newview/rlvinventory.h +++ b/indra/newview/rlvinventory.h @@ -36,11 +36,10 @@ class LLOfferInfo; class RlvInventory : public LLSingleton, public LLInventoryObserver { -protected: - RlvInventory(); -public: + LLSINGLETON(RlvInventory); ~RlvInventory(); +public: // LLInventoryObserver override /*virtual*/ void changed(U32 mask); @@ -103,7 +102,6 @@ protected: private: static const std::string cstrSharedRoot; friend class RlvSharedInventoryFetcher; - friend class LLSingleton; }; // ============================================================================ diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index bdbfc35170..e5fee413f5 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -140,9 +140,7 @@ extern RlvAttachmentLocks gRlvAttachmentLocks; // TODO-RLVa: [RLVa-1.2.1] This class really looks rather cluttered so look into cleaning it up/simplifying it a bit class RlvAttachmentLockWatchdog : public LLSingleton { - friend class LLSingleton; -protected: - RlvAttachmentLockWatchdog() : m_pTimer(NULL) {} + LLSINGLETON(RlvAttachmentLockWatchdog); ~RlvAttachmentLockWatchdog() { delete m_pTimer; } /* @@ -217,6 +215,8 @@ protected: } *m_pTimer; }; +inline RlvAttachmentLockWatchdog::RlvAttachmentLockWatchdog() : m_pTimer(NULL) {} + // ============================================================================ // RlvWearableLocks class declaration - modelled on RlvAttachmentLocks (attach pt = wearable type - attachment = wearable) // @@ -283,9 +283,10 @@ extern RlvWearableLocks gRlvWearableLocks; class RlvFolderLocks : public LLSingleton { friend class RlvLockedDescendentsCollector; -public: - RlvFolderLocks(); + LLSINGLETON(RlvFolderLocks); + +public: // Specifies the source of a folder lock enum ELockSourceType { @@ -381,8 +382,6 @@ protected: mutable uuid_vec_t m_LockedAttachmentRem; mutable folderlock_map_t m_LockedFolderMap; mutable uuid_vec_t m_LockedWearableRem; -private: - friend class LLSingleton; }; // ============================================================================ diff --git a/indra/newview/rlvui.h b/indra/newview/rlvui.h index 81926974ee..fc6d0ce477 100644 --- a/indra/newview/rlvui.h +++ b/indra/newview/rlvui.h @@ -28,9 +28,9 @@ class RlvUIEnabler : public LLSingleton { + LLSINGLETON(RlvUIEnabler); + protected: - RlvUIEnabler(); - friend class LLSingleton; friend class RlvHandler; /* diff --git a/indra/newview/sanitycheck.cpp b/indra/newview/sanitycheck.cpp index b089f4f848..18c9f20701 100644 --- a/indra/newview/sanitycheck.cpp +++ b/indra/newview/sanitycheck.cpp @@ -27,15 +27,6 @@ #include "llviewercontrol.h" #include "sanitycheck.h" -SanityCheck::SanityCheck() -: LLSingleton() -{ -} - -SanityCheck::~SanityCheck() -{ -} - void SanityCheck::init() { struct f : public LLControlGroup::ApplyFunctor diff --git a/indra/newview/sanitycheck.h b/indra/newview/sanitycheck.h index c087fd45ec..f9c5177e25 100644 --- a/indra/newview/sanitycheck.h +++ b/indra/newview/sanitycheck.h @@ -26,19 +26,15 @@ class LLControlVariable; -class SanityCheck -: public LLSingleton +class SanityCheck : public LLSingleton { - friend class LLSingleton; + LLSINGLETON_EMPTY_CTOR(SanityCheck); + ~SanityCheck() { }; - private: - SanityCheck(); - ~SanityCheck(); +public: + void init(); - public: - void init(); - - static void onSanity(LLControlVariable* controlp); + static void onSanity(LLControlVariable* controlp); }; #endif // SANITYCHECK_H diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index c9dea6164f..4407112364 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -156,6 +156,7 @@ with the same filename but different name + diff --git a/indra/newview/skins/default/textures/toolbar_icons/report_abuse.png b/indra/newview/skins/default/textures/toolbar_icons/report_abuse.png new file mode 100644 index 0000000000..d5cb6ca259 Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/report_abuse.png differ diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index 5fca159d54..02e7fa2990 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -32,6 +32,7 @@ libcurl Version: [LIBCURL_VERSION] J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] Qt Webkit Version: [QT_WEBKIT_VERSION] +LibVLC Version: [LIBVLC_VERSION] Voice Server Version: [VOICE_VERSION] diff --git a/indra/newview/skins/default/xui/en/floater_fs_area_search.xml b/indra/newview/skins/default/xui/en/floater_fs_area_search.xml index 759702a71c..d0a8e57c2f 100644 --- a/indra/newview/skins/default/xui/en/floater_fs_area_search.xml +++ b/indra/newview/skins/default/xui/en/floater_fs_area_search.xml @@ -8,6 +8,7 @@ width="610" height="435" save_rect="true" + single_instance="true" can_resize="true" can_minimize="true" can_close="true" diff --git a/indra/newview/skins/default/xui/en/floater_fs_group_titles.xml b/indra/newview/skins/default/xui/en/floater_fs_group_titles.xml index dd343cdf3a..e35014d2ea 100644 --- a/indra/newview/skins/default/xui/en/floater_fs_group_titles.xml +++ b/indra/newview/skins/default/xui/en/floater_fs_group_titles.xml @@ -8,6 +8,7 @@ min_width="250" min_height="150" save_rect="true" + single_instance="true" can_resize="true" can_minimize="true" can_close="true" diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 28c89868bd..34fa0b0fe9 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -121,7 +121,6 @@ follows="all" layout="topleft" name="conversations_list_panel" - opaque="true" top_pad="0" left="5" right="-1"/> @@ -144,7 +143,6 @@ follows="all" layout="topleft" name="stub_panel" - opaque="true" top_pad="0" left="0" right="-1"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index bda12a5401..5f3454fdcd 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1535,7 +1535,20 @@ Are you sure you want to delete this notecard? notext="Cancel" yestext="OK"/> - + + + +Do you want to use previous screenshot for your report? + confirm + + + - + + +Unable to add new entry to block list because you reached the limit of [MUTE_LIMIT] entries. + fail + + + width="225"> unknown Places Preferences Profile + Report Abuse Search Snapshot Speak @@ -2636,6 +2637,7 @@ Try enclosing path to the editor with double quotes. Places you've saved (ALT+H) Preferences (CTRL+P) Edit or view your profile + Report Abuse Find places, events, people (CTRL+F) Take a picture (CTRL+SHIFT+S) Speak with people nearby using your microphone diff --git a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml index 1545a6febb..1511116ba6 100644 --- a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml +++ b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml @@ -5,8 +5,7 @@ follows="left|top" > - diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 7a06572037..cbf66ddbde 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -67,7 +67,8 @@ Versión de libcurl: [LIBCURL_VERSION] Versión de J2C Decoder: [J2C_VERSION] Versión de Audio Driver: [AUDIO_DRIVER_VERSION] Versión de LLCEFLib/CEF: [LLCEFLIB_VERSION] -Versión de Voice Server: [VOICE_VERSION] +Versión de LibVLC: [LIBVLC_VERSION] +Versión del servidor de voz: [VOICE_VERSION] Paquetes perdidos: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 79b463c097..6a186c269a 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -59,6 +59,7 @@ Version libcurl : [LIBCURL_VERSION] Version J2C Decoder : [J2C_VERSION] Version Audio Driver : [AUDIO_DRIVER_VERSION] Version LLCEFLib/CEF : [LLCEFLIB_VERSION] +Version LibVLC : [LIBVLC_VERSION] Version serveur vocal : [VOICE_VERSION] diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 0fa8aab413..ef5aec4175 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -74,6 +74,7 @@ SLURL: <nolink>[SLURL]</nolink> Версия декодера J2C: [J2C_VERSION] Версия драйвера звука: [AUDIO_DRIVER_VERSION] Версия LLCEFLib/CEF: [LLCEFLIB_VERSION] +Версия LibVLC: [LIBVLC_VERSION] Версия голосового сервера: [VOICE_VERSION] diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index deb67d97a9..e757bfd5d3 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -71,7 +71,8 @@ libcurl Sürümü: [LIBCURL_VERSION] J2C Kod Çözücü Sürümü: [J2C_VERSION] Ses Sürücüsü Sürümü: [AUDIO_DRIVER_VERSION] LLCEFLib/CEF Sürümü: [LLCEFLIB_VERSION] -Ses Sunucu Sürümü: [VOICE_VERSION] +LibVLC Sürümü: [LIBVLC_VERSION] +Ses Sunucusu Sürümü: [VOICE_VERSION] Kaybolan Paketler: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) diff --git a/indra/newview/skins/vintage/xui/en/floater_tools.xml b/indra/newview/skins/vintage/xui/en/floater_tools.xml old mode 100755 new mode 100644 diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp index ea5014a59c..4f7f87b6b0 100644 --- a/indra/newview/tests/llremoteparcelrequest_test.cpp +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -34,6 +34,7 @@ #include "../llagent.h" #include "message.h" #include "llurlentry.h" +#include "llpounceable.h" namespace { const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111"); @@ -62,7 +63,7 @@ void LLMessageSystem::addUUID(char const *,LLUUID const &) { } void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { } void LLMessageSystem::nextBlockFast(char const *) { } void LLMessageSystem::newMessage(char const *) { } -LLMessageSystem * gMessageSystem; +LLPounceable gMessageSystem; char const* const _PREHASH_AgentID = 0; // never dereferenced during this test char const* const _PREHASH_AgentData = 0; // never dereferenced during this test LLAgent gAgent; diff --git a/indra/newview/utilitybar.h b/indra/newview/utilitybar.h index 28747fbc28..f1bab26fe8 100644 --- a/indra/newview/utilitybar.h +++ b/indra/newview/utilitybar.h @@ -34,11 +34,8 @@ class UtilityBar : public LLSingleton, public LLEventTimer { - friend class LLSingleton; - - private: - UtilityBar(); - ~UtilityBar(); + LLSINGLETON(UtilityBar); + ~UtilityBar(); public: void init(); diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp index 8718360f0c..76063e6db1 100644 --- a/indra/test/message_tut.cpp +++ b/indra/test/message_tut.cpp @@ -103,7 +103,7 @@ namespace tut ~LLMessageSystemTestData() { // not end_messaging_system() - delete gMessageSystem; + delete static_cast(gMessageSystem); gMessageSystem = NULL; // rm contents of temp dir