Age | Commit message (Collapse) | Author |
|
LLSingleton explicitly supports circular dependencies: initialization
performed during an LLSingleton subclass's initSingleton() method may
recursively call that same subclass's getInstance() method. On the other hand,
circularity from a subclass constructor cannot be permitted, else
getInstance() would have to return a partially-constructed object.
Our dependency tracking circularity check initially forbade both. Loosen it to
permit references from within initSingleton().
|
|
llhttpclientadapter_test.cpp starts its every test by explicitly instantiating
a local LLHTTPClientAdapter object. This is an abuse of LLSingleton, and if it
had been properly defined (private constructor), it should never have compiled.
Looked at the other way, though, every known reference to LLHTTPClientAdapter
instantiates a local object. Why did someone think it should be an LLSingleton
in the first place? Remove LLSingleton<> as a base class; remove llsingleton.h.
This makes llhttpclientadapter_test.cpp work just fine.
One might also question what value this class adds. It seems to do very little
-- but more significantly, the ONLY references in the source tree are its
declaration, definition and test. Nobody actually uses it anywhere.
|
|
The forward declaration said it was a 'friend class', whereas the actual
definition is a struct. MSVC dislikes that.
|
|
Part of LLError's logging infrastructure is implemented with an LLSingleton.
Therefore, attempts to log from within LLSingleton machinery could potentially
go south if LLError's LLSingleton is not yet initialized.
Introduce LLError::is_available() in llerrorcontrol.h and llerror.cpp.
Make LLSingletonBase::logwarns() and logerrs() consult LLError::is_available()
before attempting to use LL_WARNS or LL_ERRS, respectively.
Moreover, make all LLSingleton internal logging use logwarns() and logerrs()
instead of directly engaging LL_ERRS or LL_WARNS.
|
|
Introduce LLSingleton::cleanupSingleton() canonical method as the place to put
any subclass cleanup logic that might take nontrivial realtime or throw an
exception. Neither is appropriate in a destructor.
Track all extant LLSingleton subclass instances on a master list, which
permits adding LLSingletonBase::cleanupAll() and deleteAll() methods.
Also notice when any LLSingleton subclass constructor (or initSingleton()
method) calls instance() or getInstance() for another LLSingleton, and capture
that other LLSingleton instance as a dependency of the first. This permits
cleanupAll() and deleteAll() to perform a dependency sort on the master list,
thus cleaning up (or deleting) leaf LLSingletons AFTER the LLSingletons that
depend on them.
Make C++ runtime's final static destructor call LLSingletonBase::deleteAll()
instead of deleting individual LLSingleton instances in arbitrary order.
Eliminate "llerror.h" from llsingleton.h, a longstanding TODO.
|
|
|
|
Changing the queue-of-callables implementation to boost::signals2::signal,
which is noncopyable, means that LLPounceable itself should be noncopyable.
|
|
Vir points out that "queue of callables" is pretty much exactly what a signal
does.
Add unit tests to verify chronological order, also queue reset when fired.
|
|
|
|
LLSingleton currently presents two different usage styles: deriving MyClass
from LLSingleton<MyClass>, or just using a typedef. Turns out LLGlobalEconomy
is the ONLY class using the typedef style -- and the apologetic comment talks
about a potential maintenance that hasn't actually happened.
Derive LLGlobalEconomy from LLSingleton<LLGlobalEconomy>, like everyone else.
|
|
|
|
to a new llcommon/llinitdestroyclass.h.
This mechanism is so general -- but has so many related moving parts -- that
(a) it deserves to be in a header file all its own, instead of conflated with
llui.h, and (b) it should be in llcommon where anyone can use it. It has no
dependencies whatsoever on llui or anything viewer-specific.
In this very changeset we changed one #include "llui.h" whose comment admits
that it was only dragged in for LLDestroyClass.
|
|
The LLMuteList singleton instance might be requested before gMessageSystem is
constructed. LLMuteList wants to register a couple gMessageSystem callbacks.
Since gMessageSystem is not (yet) itself an LLSingleton, LLMuteList's
constructor can't just call it into existence. Until now, LLMuteList overrode
LLSingleton's getInstance() method: every time getInstance() was called, the
subclass override method would check whether gMessageSystem had been
initialized, and if so, register its callbacks before forwarding the call to
the base-class LLSingleton::getInstance() method.
Change to use LLPounceable::callWhenReady() instead.
This is the reason gMessageSystem was made an LLPounceable.
|
|
|
|
Changing to IFF in the lex/yacc sources (which are supposedly deprecated on
the viewer side anyway!) unbreaks Mac builds.
|
|
|
|
Now that gMessageSystem is an LLPounceable, we would either have to define
comparisons to LLPounceable's held type or static_cast<LLMessageSystem*> to
literally compare to NULL. But since we already define operator bool(), that's
the easy (and idiomatic) fix.
|
|
This will permit other subsystems to use gMessageSystem.callWhenReady() to (e.g.)
register callbacks as soon as gMessageSystem is fully initialized.
|
|
LLMuteList, an LLSingleton, overrides its getInstance() method to intercept
control every time a consumer wants LLMuteList. This "polling" is to notice
when gMessageSystem becomes non-NULL, and register a couple callbacks on it.
Unfortunately there are a couple ways to request the LLMuteList instance
without specifically calling the subclass getInstance(), which would bypass
that logic. Moreover, the polling feels a bit dubious to start with.
LLPounceable<T*> presents an idiom in which you can callWhenReady(callable) on
the LLPounceable instance. If the T* is already non-NULL, it calls the
callable immediately; otherwise it enqueues it for when the T* is set
non-NULL. (This lets you "pounce" on the T* as soon as it becomes available,
hence the name.) So if gMessageSystem were an LLPounceable<LLMessageSystem*>,
LLMuteList's constructor could simply call gMessageSystem.callWhenReady() and
relax: the callbacks would be registered either on LLMuteList construction or
LLMessageSystem initialization, whichever comes later.
LLPounceable comes with its very own set of unit tests. However, as of this
commit it is not yet used in actual viewer code.
|
|
Remove evil getIfExists() method, used by no one.
Remove evil destroyed() method, used in exactly three places -- one of which
is a test. Replace with equally evil instanceExists() method, which is used
EVERYWHERE -- sigh.
|
|
and use it for existing LLSomeClass::cleanupClass() calls.
This logs the fact of making the call, as well as making it.
|
|
|
|
|
|
|
|
mass add of wearables/objects
|
|
|
|
in inventory panel the same way we do now in appearance tab
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wide char paths; on other platforms they are now just typedefs to the std classes
|
|
|
|
respectively
|
|
respectively
|
|
|
|
|
|
|
|
|
|
exit)
|
|
|
|
|
|
|
|
|