chaninsaw surgery to resolve the most urgent dependency problems with lib
This commit is contained in:
parent
bdffc18101
commit
e8469d5552
12 changed files with 156 additions and 118 deletions
|
|
@ -32,6 +32,7 @@ liblumieracommon_la_SOURCES = \
|
|||
$(liblumieracommon_la_srcdir)/config_lookup.c \
|
||||
$(liblumieracommon_la_srcdir)/config_interface.c \
|
||||
$(liblumieracommon_la_srcdir)/configrules.cpp \
|
||||
$(liblumieracommon_la_srcdir)/external/libgavl.cpp \
|
||||
$(liblumieracommon_la_srcdir)/query/fake-configrules.cpp \
|
||||
$(liblumieracommon_la_srcdir)/interface.c \
|
||||
$(liblumieracommon_la_srcdir)/interfaceregistry.c \
|
||||
|
|
@ -42,8 +43,7 @@ liblumieracommon_la_SOURCES = \
|
|||
$(liblumieracommon_la_srcdir)/appstate.cpp \
|
||||
$(liblumieracommon_la_srcdir)/option.cpp \
|
||||
$(liblumieracommon_la_srcdir)/subsys.cpp \
|
||||
$(liblumieracommon_la_srcdir)/interfaceproxy.cpp \
|
||||
$(liblumieracommon_la_srcdir)/nobugcfg.cpp
|
||||
$(liblumieracommon_la_srcdir)/interfaceproxy.cpp
|
||||
|
||||
|
||||
noinst_HEADERS += \
|
||||
|
|
@ -57,6 +57,7 @@ noinst_HEADERS += \
|
|||
$(liblumieracommon_la_srcdir)/config_lookup.h \
|
||||
$(liblumieracommon_la_srcdir)/config_interface.h \
|
||||
$(liblumieracommon_la_srcdir)/configrules.hpp \
|
||||
$(liblumieracommon_la_srcdir)/external/libgavl.hpp \
|
||||
$(liblumieracommon_la_srcdir)/query/fake-configrules.hpp \
|
||||
$(liblumieracommon_la_srcdir)/subsys.hpp \
|
||||
$(liblumieracommon_la_srcdir)/appstate.hpp \
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "include/lifecycle.h"
|
||||
#include "common/appstate.hpp"
|
||||
#include "lib/lifecycleregistry.hpp"
|
||||
#include "common/subsystem-runner.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -51,7 +50,16 @@ namespace lumiera {
|
|||
{
|
||||
if (const char * errorstate = lumiera_error ())
|
||||
ERROR (NOBUG_ON, "*** Unexpected error: %s\n Triggering emergency exit.", errorstate);
|
||||
} }
|
||||
}
|
||||
|
||||
void
|
||||
createAppStateInstance(){
|
||||
AppState::instance();
|
||||
}
|
||||
|
||||
LifecycleHook schedule_ (ON_BASIC_INIT, &createAppStateInstance);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -67,13 +75,10 @@ namespace lumiera {
|
|||
* client codes POV it just behaves like intended).
|
||||
*/
|
||||
AppState::AppState()
|
||||
: lifecycleHooks_(new LifecycleRegistry)
|
||||
, subsystems_(0)
|
||||
: subsystems_(0)
|
||||
, emergency_(false)
|
||||
, core_up_ (false)
|
||||
{
|
||||
lifecycleHooks_->execute (ON_BASIC_INIT); // note in most cases a NOP
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
|
|
@ -88,14 +93,6 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
void
|
||||
AppState::lifecycle (Symbol event_label)
|
||||
{
|
||||
instance().lifecycleHooks_->execute(event_label);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -124,7 +121,7 @@ namespace lumiera {
|
|||
_THROW_IF
|
||||
|
||||
core_up_= true;
|
||||
AppState::lifecycle (ON_GLOBAL_INIT);
|
||||
LifecycleHook::trigger (ON_GLOBAL_INIT);
|
||||
_THROW_IF
|
||||
|
||||
|
||||
|
|
@ -173,12 +170,12 @@ namespace lumiera {
|
|||
if (emergency_)
|
||||
{
|
||||
ERROR (operate, "Triggering emergency exit...");
|
||||
lifecycle (ON_EMERGENCY);
|
||||
LifecycleHook::trigger (ON_EMERGENCY);
|
||||
return CLEAN_EMERGENCY_EXIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
lifecycle (ON_GLOBAL_SHUTDOWN);
|
||||
LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN);
|
||||
return NORMAL_EXIT;
|
||||
}
|
||||
}
|
||||
|
|
@ -219,12 +216,12 @@ namespace lumiera {
|
|||
|
||||
if (emergency_)
|
||||
{
|
||||
lifecycle (ON_EMERGENCY);
|
||||
LifecycleHook::trigger (ON_EMERGENCY);
|
||||
return FAILED_EMERGENCY_EXIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
lifecycle (ON_GLOBAL_SHUTDOWN);
|
||||
LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN);
|
||||
return CLEAN_EXIT_AFTER_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
@ -256,70 +253,4 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
|
||||
// ==== implementation LifecycleHook class =======
|
||||
|
||||
typedef LifecycleRegistry::Hook Callback;
|
||||
|
||||
|
||||
LifecycleHook::LifecycleHook (Symbol eventLabel, Callback callbackFun)
|
||||
{
|
||||
add (eventLabel,callbackFun);
|
||||
}
|
||||
|
||||
void
|
||||
LifecycleHook::add (Symbol eventLabel, Callback callbackFun)
|
||||
{
|
||||
bool isNew = AppState::instance().lifecycleHooks_->enroll (eventLabel,callbackFun);
|
||||
|
||||
if (isNew && !strcmp(ON_BASIC_INIT, eventLabel))
|
||||
callbackFun(); // when this code executes,
|
||||
// then per definition we are already post "basic init"
|
||||
// (which happens in the AppState ctor); thus fire it immediately
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LifecycleHook::trigger (Symbol eventLabel)
|
||||
{
|
||||
AppState::lifecycle (eventLabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Symbol ON_BASIC_INIT ("ON_BASIC_INIT");
|
||||
Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
|
||||
Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
|
||||
|
||||
Symbol ON_EMERGENCY ("ON_EMERGENCY");
|
||||
|
||||
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */
|
||||
|
||||
|
||||
extern const char * lumiera_ON_BASIC_INIT = lumiera::ON_BASIC_INIT;
|
||||
extern const char * lumiera_ON_GLOBAL_INIT = lumiera::ON_GLOBAL_INIT;
|
||||
extern const char * lumiera_ON_GLOBAL_SHUTDOWN = lumiera::ON_GLOBAL_SHUTDOWN;
|
||||
|
||||
extern const char * lumiera_ON_EMERGENCY = lumiera::ON_EMERGENCY;
|
||||
|
||||
|
||||
|
||||
void
|
||||
lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void))
|
||||
{
|
||||
lumiera::LifecycleHook (eventLabel, callbackFun);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_Lifecycle_trigger (const char* eventLabel)
|
||||
{
|
||||
lumiera::AppState::lifecycle (eventLabel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ namespace lumiera {
|
|||
using boost::scoped_ptr;
|
||||
using boost::noncopyable;
|
||||
|
||||
class LifecycleRegistry;
|
||||
class SubsystemRunner;
|
||||
|
||||
|
||||
|
|
@ -78,11 +77,6 @@ namespace lumiera {
|
|||
static AppState& instance();
|
||||
|
||||
|
||||
/** fire off all lifecycle callbacks
|
||||
* registered under the given label */
|
||||
static void lifecycle (Symbol eventLabel);
|
||||
|
||||
|
||||
/** evaluate the result of option parsing and maybe additional configuration
|
||||
* such as to be able to determine the further behaviour of the application.
|
||||
* Set the internal state within this object accordingly. */
|
||||
|
|
@ -123,17 +117,13 @@ namespace lumiera {
|
|||
|
||||
|
||||
private:
|
||||
typedef scoped_ptr<LifecycleRegistry> PLife;
|
||||
typedef scoped_ptr<SubsystemRunner> PSub;
|
||||
|
||||
PLife lifecycleHooks_;
|
||||
PSub subsystems_;
|
||||
|
||||
bool emergency_;
|
||||
bool core_up_;
|
||||
|
||||
friend class LifecycleHook;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
|
||||
#include "proc/common.hpp"
|
||||
#include "lib/external/libgavl.hpp"
|
||||
#include "common/external/libgavl.hpp"
|
||||
#include "proc/control/stypemanager.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -36,8 +36,9 @@ liblumiera_la_SOURCES = \
|
|||
$(liblumiera_la_srcdir)/time.c \
|
||||
$(liblumiera_la_srcdir)/resourcecollector.c \
|
||||
$(liblumiera_la_srcdir)/allocationcluster.cpp \
|
||||
$(liblumiera_la_srcdir)/external/libgavl.cpp \
|
||||
$(liblumiera_la_srcdir)/lumitime.cpp \
|
||||
$(liblumiera_la_srcdir)/lifecycle.cpp \
|
||||
$(liblumiera_la_srcdir)/nobugcfg.cpp \
|
||||
$(liblumiera_la_srcdir)/util.cpp \
|
||||
$(liblumiera_la_srcdir)/visitor.cpp \
|
||||
$(liblumiera_la_srcdir)/query.cpp \
|
||||
|
|
@ -64,7 +65,6 @@ noinst_HEADERS += \
|
|||
$(liblumiera_la_srcdir)/allocationcluster.hpp \
|
||||
$(liblumiera_la_srcdir)/scopedholdertransfer.hpp \
|
||||
$(liblumiera_la_srcdir)/scopedholder.hpp \
|
||||
$(liblumiera_la_srcdir)/external/libgavl.hpp \
|
||||
$(liblumiera_la_srcdir)/lifecycleregistry.hpp \
|
||||
$(liblumiera_la_srcdir)/factory.hpp \
|
||||
$(liblumiera_la_srcdir)/frameid.hpp \
|
||||
|
|
|
|||
101
src/lib/lifecycle.cpp
Normal file
101
src/lib/lifecycle.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Lifecycle - registering and triggering lifecycle callbacks
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "include/lifecycle.h"
|
||||
#include "lib/lifecycleregistry.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
using util::cStr;
|
||||
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
|
||||
|
||||
// ==== implementation LifecycleHook class =======
|
||||
|
||||
typedef LifecycleRegistry::Hook Callback;
|
||||
|
||||
|
||||
LifecycleHook::LifecycleHook (Symbol eventLabel, Callback callbackFun)
|
||||
{
|
||||
add (eventLabel,callbackFun);
|
||||
}
|
||||
|
||||
void
|
||||
LifecycleHook::add (Symbol eventLabel, Callback callbackFun)
|
||||
{
|
||||
bool isNew = LifecycleRegistry::instance().enroll (eventLabel,callbackFun);
|
||||
|
||||
if (isNew && !strcmp(ON_BASIC_INIT, eventLabel))
|
||||
callbackFun(); // when this code executes,
|
||||
// then per definition we are already post "basic init"
|
||||
// (which happens in the AppState ctor); thus fire it immediately
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LifecycleHook::trigger (Symbol eventLabel)
|
||||
{
|
||||
LifecycleRegistry::instance().execute (eventLabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Symbol ON_BASIC_INIT ("ON_BASIC_INIT");
|
||||
Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
|
||||
Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
|
||||
|
||||
Symbol ON_EMERGENCY ("ON_EMERGENCY");
|
||||
|
||||
|
||||
} // namespace lumiera
|
||||
|
||||
|
||||
extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */
|
||||
|
||||
|
||||
extern const char * lumiera_ON_BASIC_INIT = lumiera::ON_BASIC_INIT;
|
||||
extern const char * lumiera_ON_GLOBAL_INIT = lumiera::ON_GLOBAL_INIT;
|
||||
extern const char * lumiera_ON_GLOBAL_SHUTDOWN = lumiera::ON_GLOBAL_SHUTDOWN;
|
||||
|
||||
extern const char * lumiera_ON_EMERGENCY = lumiera::ON_EMERGENCY;
|
||||
|
||||
|
||||
|
||||
void
|
||||
lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void))
|
||||
{
|
||||
lumiera::LifecycleHook (eventLabel, callbackFun);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_Lifecycle_trigger (const char* eventLabel)
|
||||
{
|
||||
lumiera::LifecycleRegistry::instance().execute (eventLabel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
#include <tr1/functional>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "lib/util.hpp"
|
||||
|
|
@ -49,6 +50,7 @@
|
|||
|
||||
namespace lumiera {
|
||||
|
||||
using boost::scoped_ptr;
|
||||
using boost::noncopyable;
|
||||
using std::tr1::function;
|
||||
using util::contains;
|
||||
|
|
@ -89,11 +91,25 @@ namespace lumiera {
|
|||
}
|
||||
|
||||
|
||||
/** get the (single) LifecycleRegistry instance.
|
||||
* @warning don't use it after the end of main()! */
|
||||
static LifecycleRegistry& instance() // Meyer's singleton
|
||||
{
|
||||
static scoped_ptr<LifecycleRegistry> theRegistry_;
|
||||
if (!theRegistry_) theRegistry_.reset (new LifecycleRegistry ());
|
||||
return *theRegistry_;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::map<const string, Callbacks> table_;
|
||||
|
||||
LifecycleRegistry () {}
|
||||
friend class AppState;
|
||||
LifecycleRegistry () {
|
||||
execute (ON_BASIC_INIT); // just to be sure, typically a NOP, because nothing is registered yet
|
||||
}
|
||||
|
||||
~LifecycleRegistry () {}
|
||||
friend void boost::checked_delete<LifecycleRegistry>(LifecycleRegistry*);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace lumiera {
|
|||
* http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_10
|
||||
* @param SI the class of the Singleton instance
|
||||
* @param Create policy defining how to create/destroy the instance
|
||||
* @oaram Life policy defining how to manage Singleton Lifecycle
|
||||
* @param Life policy defining how to manage Singleton Lifecycle
|
||||
*/
|
||||
template
|
||||
< class SI
|
||||
|
|
@ -133,12 +133,14 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
///// TODO: get rid of the static fields?
|
||||
///// is tricky because of invoking the destructors. If we rely on instance vars,
|
||||
///// Question: can we get rid of the static fields?
|
||||
///// this is tricky because of invoking the destructors. If we rely on instance vars,
|
||||
///// the object may already have been released when the runtime system calls the
|
||||
///// destructors of static objects at shutdown.
|
||||
///// It seems this would either cost us much of the flexibility or get complicated
|
||||
///// to a point where we could as well implement our own Dependency Injection Manager.
|
||||
///// But the whole point of my pervasive use of this singleton template is to remain
|
||||
///// below this borderline of integration ("IoC yes, but avoid DI").
|
||||
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,15 +25,13 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "common/appstate.hpp"
|
||||
#include "include/lifecycle.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace lumiera
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
namespace lumiera {
|
||||
namespace test {
|
||||
|
||||
uint basicInit (0);
|
||||
uint customCallback (0);
|
||||
|
|
@ -41,13 +39,13 @@ namespace lumiera
|
|||
void basicInitHook () { ++basicInit; }
|
||||
void myCallback() { ++customCallback; }
|
||||
|
||||
Symbol MY_MAGIC_MEGA_EVENT = "dial M for murder";
|
||||
Symbol MY_DEADLY_EVENT = "dial M for murder";
|
||||
|
||||
|
||||
namespace // register them to be invoked by lifecycle event id
|
||||
{
|
||||
LifecycleHook _schedule1 (ON_BASIC_INIT, &basicInitHook);
|
||||
LifecycleHook _schedule2 (MY_MAGIC_MEGA_EVENT, &myCallback);
|
||||
LifecycleHook _schedule2 (MY_DEADLY_EVENT, &myCallback);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -64,7 +62,7 @@ namespace lumiera
|
|||
ASSERT (1 == basicInit, "the basic-init callback has been invoked more than once");
|
||||
|
||||
ASSERT (!customCallback);
|
||||
AppState::lifecycle (MY_MAGIC_MEGA_EVENT);
|
||||
LifecycleHook::trigger (MY_DEADLY_EVENT);
|
||||
ASSERT ( 1 == customCallback);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@
|
|||
|
||||
#include "lib/test/suite.hpp"
|
||||
#include "lib/test/testoption.hpp"
|
||||
#include "common/appstate.hpp"
|
||||
#include "include/lifecycle.h"
|
||||
|
||||
using lumiera::AppState;
|
||||
using lumiera::LifecycleHook;
|
||||
using lumiera::ON_GLOBAL_INIT;
|
||||
using lumiera::ON_GLOBAL_SHUTDOWN;
|
||||
|
||||
|
|
@ -40,13 +39,13 @@ int main (int argc, const char* argv[])
|
|||
util::Cmdline args (argc,argv);
|
||||
test::TestOption optparser (args);
|
||||
test::Suite suite (optparser.getTestgroup());
|
||||
AppState::lifecycle(ON_GLOBAL_INIT);
|
||||
LifecycleHook::trigger (ON_GLOBAL_INIT);
|
||||
|
||||
if (optparser.getDescribe())
|
||||
suite.describe();
|
||||
else
|
||||
suite.run (args);
|
||||
|
||||
AppState::lifecycle(ON_GLOBAL_SHUTDOWN);
|
||||
LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue