chaninsaw surgery to resolve the most urgent dependency problems with lib

This commit is contained in:
Fischlurch 2009-01-14 12:15:13 +01:00
parent bdffc18101
commit e8469d5552
12 changed files with 156 additions and 118 deletions

View file

@ -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 \

View file

@ -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);
}
}

View file

@ -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;
};

View file

@ -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" {

View file

@ -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
View 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);
}
}

View file

@ -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*);
};

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}