start using the new lifecycle hooks. remove global nobugcfg.h

Now using proc/lumiera.hpp and proc/nobugcfg.hpp (i.e. only for the proc-Layer). Using ON_BASIC_INIT to
pull up NoBug automatically and for installing the unknown-exception handler. Add calls for
ON_GLOBAL_INIT and ON_GLOBAL_SHUTDOWN hooks to main() and to the testrunner
This commit is contained in:
Fischlurch 2008-04-14 05:15:16 +02:00
parent 85189d3f4c
commit 3e8996005e
34 changed files with 171 additions and 135 deletions

View file

@ -24,7 +24,7 @@
#include "common/cmdline.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>

View file

@ -24,7 +24,7 @@
#include "common/configrules.hpp"
#include "common/query/mockconfigrules.hpp"
//#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"

View file

@ -189,6 +189,11 @@ namespace lumiera
}
void install_unexpectedException_handler ()
{
std::set_unexpected (lumiera_unexpectedException);
}
} // namespace error
} // namespace lumiera

View file

@ -25,7 +25,7 @@
#define LUMIERA_ERROR_HPP_
#include <string>
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include "lib/error.h"
@ -150,6 +150,14 @@ namespace lumiera
LUMIERA_EXCEPTION_DECLARE (External, Error, LUMIERA_ERROR_EXTERNAL);
/** install our own handler for undeclared exceptions. Will be
* called automatically ON_BASIC_INIT when including errror.hpp
* @see appconfig.hpp */
void install_unexpectedException_handler ();
namespace {
LifecycleHook schedule_ (ON_BASIC_INIT, &install_unexpectedException_handler);
}
} // namespace error
} // namespace lumiera

View file

@ -26,7 +26,7 @@
#ifndef LUMIERA_MULTITHREAD_H
#define LUMIERA_MULTITHREAD_H
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include "common/util.hpp"

View file

@ -23,7 +23,7 @@
#include "common/query.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>

View file

@ -28,8 +28,8 @@
#include "proc/asset/pipe.hpp"
#include "proc/nobugcfg.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
using util::isnil;

View file

@ -38,7 +38,7 @@ This code is heavily inspired by
#include "common/singletonpolicies.hpp" ///< several Policies usable together with SingletonFactory
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"

View file

@ -28,7 +28,7 @@
#include "pre.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include "common/test/suite.hpp"
#include "common/util.hpp"

View file

@ -30,7 +30,7 @@
#include <sstream>
#include <boost/algorithm/string.hpp>
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include "common/cmdline.hpp"
#include "common/test/suite.hpp"
#include "common/test/run.hpp"

View file

@ -24,7 +24,6 @@
#include "common/test/testoption.hpp"
#include "common/test/suite.hpp"
#include "nobugcfg.h"
#include "common/error.hpp"

View file

@ -2,7 +2,7 @@
Appconfig - for global initialization and configuration
Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.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
@ -21,16 +21,10 @@
* *****************************************************/
#include "common/appconfig.hpp"
#include "lib/appconfig.hpp"
#include "common/error.hpp"
#include "common/util.hpp"
#define NOBUG_INIT_DEFS_
#include "nobugcfg.h"
#undef NOBUG_INIT_DEFS_
#include <exception>
using util::isnil;
using util::cStr;
@ -43,6 +37,10 @@ namespace lumiera
#define LUMIERA_VERSION 0++devel
#endif
Symbol ON_BASIC_INIT ("ON_BASIC_INIT");
Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
/** perform initialization triggered on first access.
* Will execute the ON_BASIC_INIT hook, but under typical
@ -50,24 +48,16 @@ namespace lumiera
* added to this hook, the Appconfig singleton instance has
* already been created. For this reason, there is special
* treatment for the ON_BASIC_INIT in LifecycleHook::add,
* causing the provided callbacks being fired immediately.
* (btw, this is nothing to be worried of, for the client
* code it just behaves like intended).
* causing the provided callbacks to be fired immediately.
* (btw, this is nothing to be worried of, because from
* client codes POV it just behaves like intended).
*/
Appconfig::Appconfig()
: configParam_ (new Configmap),
lifecycleHooks_(new LifecycleRegistry)
{
//////////
NOBUG_INIT;
//////////
INFO(config, "Basic application configuration triggered.");
lifecycleHooks_->execute (ON_BASIC_INIT); // note in most cases a NOP
// install our own handler for undeclared exceptions
std::set_unexpected (lumiera::error::lumiera_unexpectedException);
(*configParam_)["version"] = STRINGIFY (LUMIERA_VERSION);
}
@ -81,12 +71,12 @@ namespace lumiera
try
{
const string& val = (*instance().configParam_)[key];
WARN_IF( isnil(val), config, "undefined config parameter \"%s\" requested.", key.c_str());
WARN_IF ( isnil(val), config, "undefined config parameter \"%s\" requested.", key.c_str());
return val;
}
catch (...)
{
ERROR(config, "error while accessing configuration parameter \"%s\".", key.c_str());
ERROR (config, "error while accessing configuration parameter \"%s\".", key.c_str());
static string NOTFOUND ("");
return NOTFOUND;
} }
@ -114,9 +104,9 @@ namespace lumiera
LifecycleHook&
LifecycleHook::add (Symbol eventLabel, Callback callbackFun)
{
Appconfig::instance().lifecycleHooks_->enroll (eventLabel,callbackFun);
bool isNew = Appconfig::instance().lifecycleHooks_->enroll (eventLabel,callbackFun);
if (!strcmp(ON_BASIC_INIT, eventLabel))
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 Appconfig ctor); thus fire it immediately

View file

@ -2,8 +2,7 @@
APPCONFIG.hpp - for global initialization and configuration
Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org>
Hermann Vosseler <Ichthyostega@web.de>
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
@ -44,9 +43,7 @@
#include <string>
#include <boost/scoped_ptr.hpp>
#include <boost/noncopyable.hpp>
#include "common/lifecycleregistry.hpp"
#include "nobugcfg.h"
#include "lib/lifecycleregistry.hpp"
@ -69,7 +66,8 @@ namespace lumiera
{
private:
/** perform initialization on first access.
* @see #instance() */
* @see #instance()
*/
Appconfig ();
~Appconfig () throw() {}; ///< deletion prohibited
@ -79,7 +77,7 @@ namespace lumiera
public:
/** get the (single) Appconfig instance.
* Implemented as Meyers singleton.
* @warning don't use it in destruction code!
* @warning don't use it after the end of main()!
*/
static Appconfig& instance()
{
@ -90,12 +88,11 @@ namespace lumiera
/** access the configuation value for a given key.
* @return empty string for unknown keys, config value else
*/
* @return empty string for unknown keys, config value else */
static const string & get (const string& key); // never throws
/** fire off all lifecycle callbacks
* registered under the given label */
* registered under the given label */
static void lifecycle (Symbol eventLabel);
// note: if necessary, we can add support
@ -114,9 +111,9 @@ namespace lumiera
};
Symbol ON_BASIC_INIT ("ON_BASIC_INIT"); ///< automatic static init. treated specially
Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT"); ///< to be triggered in main() @note no magic!
Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN"); ///< to be triggered at the end of main() @note no magic!
extern Symbol ON_BASIC_INIT; ///< automatic static init. treated specially
extern Symbol ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic!
extern Symbol ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic!
// client code is free to register and use additional lifecycle events

View file

@ -39,22 +39,23 @@
#define LUMIERA_LIFECYCLE_H
#include <map>
#include <vector>
//#include <string>
//#include <boost/scoped_ptr.hpp>
#include <set>
#include <string>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include "common/util.hpp"
namespace lumiera
{
// using std::string;
// using boost::scoped_ptr;
using boost::noncopyable;
using boost::function;
using util::contains;
using std::string;
typedef const char * const Symbol;
typedef const char * const Symbol; //TODO define a real Symbol class, i.e. same literal string==same pointer,
// so we don't have to store string keys in the map...
/**
@ -67,17 +68,19 @@ namespace lumiera
: private noncopyable
{
public:
typedef boost::function<void(void)> Hook;
typedef std::vector<Hook> Callbacks;
typedef void (*Hook)(void);
typedef std::set<Hook> Callbacks;
typedef Callbacks::iterator Iter;
void enroll (Symbol label, Hook& toCall)
bool enroll (const string label, Hook toCall)
{
table_[label].push_back(toCall);
return table_[label]
.insert(toCall)
.second; // true if actually stored
}
void execute (Symbol label)
void execute (const string label)
{
Callbacks& cbs (table_[label]);
Iter e = cbs.end();
@ -88,7 +91,7 @@ namespace lumiera
private:
std::map<Symbol, Callbacks> table_;
std::map<const string, Callbacks> table_;
LifecycleRegistry () {}
friend class Appconfig;

View file

@ -23,16 +23,24 @@
#include <iostream>
#include "lumiera.h"
#include "proc/lumiera.hpp"
using std::cout;
using std::endl;
using lumiera::Appconfig;
using lumiera::ON_GLOBAL_INIT;
using lumiera::ON_GLOBAL_SHUTDOWN;
int main (int argc, char* argv[])
{
cout << "*** Lumiera NLE for Linux ***" << endl
<< " Version: " << Appconfig::get("version") << endl;
<< " Version: " << Appconfig::get("version") << "\n";
Appconfig::lifecycle (ON_GLOBAL_INIT);
// great things are happening here....
Appconfig::lifecycle (ON_GLOBAL_SHUTDOWN);
return 0;
}

View file

@ -45,7 +45,7 @@
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include "lumiera.h"
#include "proc/lumiera.hpp"

View file

@ -42,7 +42,7 @@
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include "lumiera.h"
#include "proc/lumiera.hpp"
#include "proc/asset.hpp"

View file

@ -23,7 +23,7 @@
#include "proc/asset/category.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include <boost/algorithm/string.hpp>

View file

@ -29,7 +29,7 @@
#include "proc/mobject/session/clip.hpp"
#include "proc/mobject/session/mobjectfactory.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include <boost/regex.hpp>
#include <boost/format.hpp>

View file

@ -24,7 +24,7 @@
#include "proc/assetmanager.hpp"
#include "proc/asset/meta.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
namespace asset

View file

@ -24,7 +24,7 @@
#include "proc/assetmanager.hpp"
#include "proc/asset/proc.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
namespace asset

View file

@ -31,7 +31,7 @@
#include "proc/asset/structfactoryimpl.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
#include <boost/format.hpp>

View file

@ -24,7 +24,7 @@
#ifndef ENGINE_PROCESSOR_H
#define ENGINE_PROCESSOR_H
#include "lumiera.h"
#include "proc/lumiera.hpp"
#include "proc/stateproxy.hpp"

View file

@ -1,5 +1,5 @@
/*
LUMIERA.h - global definitions and common types
LUMIERA.hpp - global definitions and common types for the Proc-Layer
Copyright (C) Lumiera.org
@ -27,31 +27,13 @@
#ifdef __cplusplus
extern "C" {
#endif /* ========================== common C Part ============ */
#ifdef __cplusplus
}
#endif /* ==================== (End) common C Part ============ */
#ifndef __cplusplus
#include "nobugcfg.h"
#else /* ========================== C++-Part ================= */
/* common types frequently used... */
#include "common/util.hpp"
#include "common/time.hpp"
#include "common/appconfig.hpp" // includes NoBug via "nobugcfg.h"
#include "common/error.hpp"
#include "common/error.hpp" ///< pulls in NoBug via nobugcfg.hpp
#include "lib/appconfig.hpp"
namespace lumiera
@ -61,6 +43,4 @@ namespace lumiera
} // namespace lumiera
#endif /* ===================== (End) C++-Part ================= */
#endif /*LUMIERA_H*/

View file

@ -29,7 +29,7 @@
#include <list>
#include <tr1/memory>
#include "lumiera.h"
#include "proc/lumiera.hpp"
#include "proc/mobject/builder/buildertool.hpp"
#include "proc/mobject/placement.hpp"
#include "proc/asset.hpp" // TODO finally not needed?

View file

@ -22,7 +22,7 @@
#include "proc/mobject/session/fixture.hpp"
#include "nobugcfg.h"
#include "proc/nobugcfg.hpp"
namespace mobject
{

View file

@ -42,7 +42,7 @@
#define MOBJECT_SESSION_LOCATINGPIN_H
#include "lumiera.h"
#include "proc/lumiera.hpp"
#include <utility>
#include <tr1/memory>

View file

@ -26,7 +26,7 @@
#include <list>
#include "lumiera.h"
#include "proc/lumiera.hpp"
#include "proc/mobject/explicitplacement.hpp"

45
src/proc/nobugcfg.cpp Normal file
View file

@ -0,0 +1,45 @@
/*
NoBugCfg - NoBug definitions and initialisation for the Proc-Layer
Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org>
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 "proc/nobugcfg.hpp"
#define NOBUG_INIT_DEFS_
#include "proc/nobugcfg.hpp"
#undef NOBUG_INIT_DEFS_
namespace lumiera
{
void
initialize_NoBug ()
{
NOBUG_INIT;
#ifdef DEBUG
static uint callCount = 0;
ASSERT ( 0 == callCount++ );
#endif
}
}

View file

@ -1,5 +1,5 @@
/*
NOBUGCFG.h - global configuration and definitions for NoBug
NOBUGCFG.hpp - NoBug definitions and initialisation for the Proc-Layer
Copyright (C) Lumiera.org
@ -22,17 +22,20 @@
*/
/** @file nobugcfg.h
/** @file nobugcfg.hpp
** This header is for including and configuring NoBug.
** The idea is that configuration and some globally used flag
** declarations are to be kept in one central location. Normally,
** this header will be included by appconfig.hpp, which in turn gets
** included by lumiera.h
** this header will be included via some of the basic headers like
** error.hpp, which in turn gets included by proc/lumiera.hpp
**
** @par Besides the usual guarded declarations, this header contains
** one section with the corresponding <b>definitions</b>. This section
** is to be called by appconfig.cpp only, which deals with application
** wide configuration values contained in the Singleton class Appconfig.
** Incidentally, the constructor of Appconfig issues the NOBUG_INIT call
** is to be included once by some translation unit (currently this is
** nobugcfg.cpp) in order to generate the necessary definitions.
**
** @note this header assures automatic initialisation of NoBug
** by placing a static ctor call.
**
*/
@ -41,10 +44,9 @@
#define NOBUGCFG_H
#include <syslog.h>
/* configuration of NoBug goes here... */
#include <nobug.h>
#include "lib/appconfig.hpp"
#include "common/error.hpp" ///< make assertions throw instead of abort()
/* declare flags used throughout the code base... */
@ -54,8 +56,13 @@
NOBUG_DECLARE_FLAG(singleton);
NOBUG_DECLARE_FLAG(assetmem);
NOBUG_DECLARE_FLAG(mobjectmem);
namespace lumiera {
void initialize_NoBug ();
namespace {
LifecycleHook schedule_ (ON_BASIC_INIT, &initialize_NoBug);
} }
#endif /*NOBUGCFG_H ======= (End) Part 1: DECLARATIONS ======== */
@ -65,15 +72,6 @@
#ifdef NOBUG_INIT_DEFS_ /*========== Part 2: DEFINITIONS ========= */
/* ================================= common C Part ========= */
#ifdef __cplusplus /* ============== C++-Part ============== */
/* flags used throughout the code base... */
NOBUG_CPP_DEFINE_FLAG(config);
@ -83,11 +81,7 @@
NOBUG_CPP_DEFINE_FLAG_LIMIT(assetmem, LOG_WARNING);
NOBUG_CPP_DEFINE_FLAG_LIMIT(mobjectmem, LOG_WARNING);
#include "common/error.hpp"
#endif /* ===================== (End) C++-Part ============= */
#endif /*NOBUG_INIT_DEFS_ ==== (End) Part 2: DEFINITIONS ========= */

View file

@ -22,11 +22,11 @@
#include "common/appconfig.hpp"
#include "common/test/run.hpp"
#include "common/util.hpp"
#include "lib/appconfig.hpp"

View file

@ -24,7 +24,6 @@
#include "lib/error.h"
#include "common/error.hpp"
#include "common/appconfig.hpp"
#include "common/test/run.hpp"
#include "common/util.hpp"
@ -182,13 +181,11 @@ namespace lumiera
/** @test terminate the Application by throwing an undclared exception.
* this should result in the global unknown() handler to be called,
* so usually it will terminate the testrun.
* @note because we call Appconfig::instance(), our own unknown() handler
* gets installed and invoked, which gives additional diagnostics.*/
* @note inside error.hpp, an initialisation hook has been installed into
* Appconfig, causing our own unknown() handler to be installed and
* invoked, which gives additional diagnostics.*/
void terminateUnknown () throw()
{
lumiera::Appconfig::instance();
// will cause initialisation of Appconfig,
throw Error("You'll never get me, won't you?");
}

View file

@ -22,11 +22,11 @@
#include "common/appconfig.hpp"
#include "common/test/run.hpp"
#include "common/util.hpp"
#include "lib/appconfig.hpp"
@ -35,11 +35,11 @@ namespace lumiera
namespace test
{
bool basicInit (false);
bool customCallback (false);
uint basicInit (0);
uint customCallback (0);
void basicInitHook () { basicInit = true; }
void myCallback() { customCallback = true; }
void basicInitHook () { ++basicInit; }
void myCallback() { ++customCallback; }
Symbol MY_MAGIC_MEGA_EVENT = "dial M for murder";
@ -61,10 +61,11 @@ namespace lumiera
run (Arg arg)
{
ASSERT (basicInit, "the basic-init callback hasn't been invoked automatically");
ASSERT (1 == basicInit, "the basic-init callback has been invoked more than once");
ASSERT (!customCallback);
Appconfig::lifecycle (MY_MAGIC_MEGA_EVENT);
ASSERT ( customCallback);
ASSERT ( 1 == customCallback);
}
};

View file

@ -23,6 +23,12 @@
#include "common/test/suite.hpp"
#include "common/test/testoption.hpp"
#include "lib/appconfig.hpp"
using lumiera::Appconfig;
using lumiera::ON_GLOBAL_INIT;
using lumiera::ON_GLOBAL_SHUTDOWN;
/** run all tests or any single test specified in the first
* cmd line argument.
@ -33,10 +39,13 @@ int main (int argc, char* argv[])
util::Cmdline args (argc,argv);
test::TestOption optparser (args);
test::Suite suite (optparser.getTestgroup());
Appconfig::lifecycle(ON_GLOBAL_INIT);
if (optparser.getDescribe())
suite.describe();
else
suite.run (args);
Appconfig::lifecycle(ON_GLOBAL_SHUTDOWN);
return 0;
}