summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llinitdestroyclass.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h
index ca5c3f07de..49bcefc33d 100644
--- a/indra/llcommon/llinitdestroyclass.h
+++ b/indra/llcommon/llinitdestroyclass.h
@@ -42,6 +42,11 @@
#include <boost/signals2/signal.hpp>
#include <typeinfo>
+/**
+ * LLCallbackRegistry is an implementation detail base class for
+ * LLInitClassList and LLDestroyClassList. It's a very thin wrapper around a
+ * Boost.Signals2 signal object.
+ */
class LLCallbackRegistry
{
public:
@@ -61,6 +66,13 @@ private:
callback_signal_t 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<LLInitClassList>
@@ -70,6 +82,13 @@ private:
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<LLDestroyClassList>
@@ -79,6 +98,12 @@ private:
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<typename T>
class LLRegisterWith
{
@@ -98,37 +123,68 @@ public:
}
};
+/**
+ * Derive MyClass from LLInitClass<MyClass> (the Curiously Recurring Template
+ * Pattern) to ensure that the static method MyClass::initClass() will be
+ * called (along with all other LLInitClass<T> 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<typename T>
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<LLInitClassList> sRegister;
private:
+ // Provide a default initClass() method in case subclass misspells (or
+ // omits) initClass(). This turns a potential build error into a fatal
+ // runtime error.
static void initClass()
{
LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL;
}
};
+/**
+ * Derive MyClass from LLDestroyClass<MyClass> (the Curiously Recurring
+ * Template Pattern) to ensure that the static method MyClass::destroyClass()
+ * will be called (along with other LLDestroyClass<T> 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<typename T>
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<LLDestroyClassList> sRegister;
private:
+ // Provide a default destroyClass() method in case subclass misspells (or
+ // omits) destroyClass(). This turns a potential build error into a fatal
+ // runtime error.
static void destroyClass()
{
LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL;
}
};
+// Here's where LLInitClass<T> specifies the subclass initClass() method.
template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
+// Here's where LLDestroyClass<T> specifies the subclass destroyClass() method.
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
#endif /* ! defined(LL_LLINITDESTROYCLASS_H) */