From e8469d5552a4a18004f8ca1fe9d5b690df43c2f0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 14 Jan 2009 12:15:13 +0100 Subject: [PATCH] chaninsaw surgery to resolve the most urgent dependency problems with lib --- src/common/Makefile.am | 5 +- src/common/appstate.cpp | 103 ++++------------------- src/common/appstate.hpp | 10 --- src/{lib => common}/external/libgavl.cpp | 2 +- src/{lib => common}/external/libgavl.hpp | 0 src/lib/Makefile.am | 4 +- src/lib/lifecycle.cpp | 101 ++++++++++++++++++++++ src/lib/lifecycleregistry.hpp | 20 ++++- src/{common => lib}/nobugcfg.cpp | 0 src/lib/singletonfactory.hpp | 8 +- tests/lib/lifecycletest.cpp | 14 ++- tests/lib/mainsuite.cpp | 7 +- 12 files changed, 156 insertions(+), 118 deletions(-) rename src/{lib => common}/external/libgavl.cpp (98%) rename src/{lib => common}/external/libgavl.hpp (100%) create mode 100644 src/lib/lifecycle.cpp rename src/{common => lib}/nobugcfg.cpp (100%) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 337bf1595..bf63ed6eb 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -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 \ diff --git a/src/common/appstate.cpp b/src/common/appstate.cpp index 6d5d009f0..4bea6168b 100644 --- a/src/common/appstate.cpp +++ b/src/common/appstate.cpp @@ -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); - } - -} - diff --git a/src/common/appstate.hpp b/src/common/appstate.hpp index aa9f0aa8d..e31d75328 100644 --- a/src/common/appstate.hpp +++ b/src/common/appstate.hpp @@ -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 PLife; typedef scoped_ptr PSub; - PLife lifecycleHooks_; PSub subsystems_; bool emergency_; bool core_up_; - friend class LifecycleHook; - }; diff --git a/src/lib/external/libgavl.cpp b/src/common/external/libgavl.cpp similarity index 98% rename from src/lib/external/libgavl.cpp rename to src/common/external/libgavl.cpp index a5711584d..8cb37a12f 100644 --- a/src/lib/external/libgavl.cpp +++ b/src/common/external/libgavl.cpp @@ -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" { diff --git a/src/lib/external/libgavl.hpp b/src/common/external/libgavl.hpp similarity index 100% rename from src/lib/external/libgavl.hpp rename to src/common/external/libgavl.hpp diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 7f9d5fbf0..ab9567089 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -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 \ diff --git a/src/lib/lifecycle.cpp b/src/lib/lifecycle.cpp new file mode 100644 index 000000000..2a0a5f099 --- /dev/null +++ b/src/lib/lifecycle.cpp @@ -0,0 +1,101 @@ +/* + Lifecycle - registering and triggering lifecycle callbacks + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + 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); + } + +} + diff --git a/src/lib/lifecycleregistry.hpp b/src/lib/lifecycleregistry.hpp index 7a9c603e2..4e1bcef7c 100644 --- a/src/lib/lifecycleregistry.hpp +++ b/src/lib/lifecycleregistry.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #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 theRegistry_; + if (!theRegistry_) theRegistry_.reset (new LifecycleRegistry ()); + return *theRegistry_; + } + + private: std::map 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*); }; diff --git a/src/common/nobugcfg.cpp b/src/lib/nobugcfg.cpp similarity index 100% rename from src/common/nobugcfg.cpp rename to src/lib/nobugcfg.cpp diff --git a/src/lib/singletonfactory.hpp b/src/lib/singletonfactory.hpp index abd8a5bbf..151af7855 100644 --- a/src/lib/singletonfactory.hpp +++ b/src/lib/singletonfactory.hpp @@ -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 diff --git a/tests/lib/lifecycletest.cpp b/tests/lib/lifecycletest.cpp index e93d5e7d7..b3f909965 100644 --- a/tests/lib/lifecycletest.cpp +++ b/tests/lib/lifecycletest.cpp @@ -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); } diff --git a/tests/lib/mainsuite.cpp b/tests/lib/mainsuite.cpp index a23e37b7f..a49d99317 100644 --- a/tests/lib/mainsuite.cpp +++ b/tests/lib/mainsuite.cpp @@ -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; }