diff --git a/Makefile.am b/Makefile.am index a709c1230..c8703c6fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,9 +41,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/ \ # Only use subdirs if really needed, prefer the include scheme below #SUBDIRS += -# administrative tools -include $(top_srcdir)/admin/Makefile.am - # core include $(top_srcdir)/src/lib/Makefile.am include $(top_srcdir)/src/proc/Makefile.am diff --git a/SConstruct b/SConstruct index e38511152..8a2316996 100644 --- a/SConstruct +++ b/SConstruct @@ -28,6 +28,7 @@ CUSTOPTIONSFILE = 'custom-options' SRCDIR = 'src' BINDIR = 'bin' LIBDIR = '.libs' +PLUGDIR = '.libs' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' @@ -74,6 +75,7 @@ def setupBasicEnvironment(): , SRCDIR=SRCDIR , BINDIR=BINDIR , LIBDIR=LIBDIR + , PLUGDIR=PLUGDIR , ICONDIR=ICONDIR , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root , CPPDEFINES=['-DLUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines @@ -322,28 +324,30 @@ def defineBuildTargets(env, artifacts): # + env.PrecompiledHeader('$SRCDIR/pre_a.hpp') # ) - objapp = srcSubtree(env,'$SRCDIR/common') - objback = srcSubtree(env,'$SRCDIR/backend') - objproc = srcSubtree(env,'$SRCDIR/proc') - objlib = srcSubtree(env,'$SRCDIR/lib') - core = ( env.SharedLibrary('$LIBDIR/lumieracommon', objapp) - + env.SharedLibrary('$LIBDIR/lumierabackend', objback) - + env.SharedLibrary('$LIBDIR/lumieraproc', objproc) - + env.SharedLibrary('$LIBDIR/lumiera', objlib) - ) + + lApp = env.SharedLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common')) + lBack = env.SharedLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) + lProc = env.SharedLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) + lLib = env.SharedLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) + + core = lLib+lApp+lBack+lProc artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) - artifacts['corelib'] = core - + artifacts['corelib'] = lLib+lApp + artifacts['support'] = lLib + # building Lumiera Plugins + envPlu = env.Clone() + envPlu.Append(CPPDEFINES='LUMIERA_PLUGIN') artifacts['plugins'] = [] # currently none # the Lumiera GTK GUI - envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm']) - envgtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) - objgui = srcSubtree(envgtk,'$SRCDIR/gui') + envGtk = env.Clone() + envGtk.mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm']) + envGtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) + objgui = srcSubtree(envGtk,'$SRCDIR/gui') # render and install Icons vector_icon_dir = env.subst('$ICONDIR/svg') @@ -352,17 +356,16 @@ def defineBuildTargets(env, artifacts): + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) - guimodule = envgtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') + guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') artifacts['lumigui'] = ( guimodule - + envgtk.Program('$BINDIR/lumigui', objgui ) + + envGtk.Program('$BINDIR/lumigui', objgui ) + env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) # call subdir SConscript(s) for independent components - SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core') - SConscript(dirs=['admin'], exports='env envgtk artifacts core') - SConscript(dirs=[TESTDIR], exports='env artifacts core') + SConscript(dirs=[SRCDIR+'/tool'], exports='env envGtk artifacts core') + SConscript(dirs=[TESTDIR], exports='env envPlu artifacts core') diff --git a/admin/Makefile.am b/admin/Makefile.am deleted file mode 100644 index a8d2da160..000000000 --- a/admin/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) Lumiera.org -# 2008, Christian Thaeter -# -# 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. - -admin_srcdir = $(top_srcdir)/admin - -noinst_PROGRAMS += vgsuppression -vgsuppression_SOURCES = $(admin_srcdir)/vgsuppression.c -vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -vgsuppression_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) -ldl liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl - -noinst_PROGRAMS += rsvg-convert -rsvg_convert_SOURCES = $(admin_srcdir)/rsvg-convert.c -rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_GUI_CFLAGS) -std=gnu99 -Wall -Werror -rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2 diff --git a/admin/SConscript b/admin/SConscript deleted file mode 100644 index 2737bab7e..000000000 --- a/admin/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -# -*- python -*- -## -## SConscript - SCons buildscript for helper tools (called by SConstruct) -## - -Import('env','envgtk','artifacts','core') - -vgsuppr = env.Program('#$BINDIR/vgsuppression',['vgsuppression.c']+core) -rsvg = envgtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') - -artifacts['tools'] += [ vgsuppr ## for suppressing false valgrind alarms - + rsvg ## for rendering SVG icons (uses librsvg) - ] - -# Rendering the SVG Icons depends on rsvg-convert -env.Depends(artifacts['icons'], rsvg) - diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index a8a76a600..159dc4721 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -91,6 +91,38 @@ def globRootdirs(roots): +def findSrcTrees(location, patterns=SRCPATTERNS): + """ find possible source tree roots, starting with the given location. + When delving down from the initial location(s), a source tree is defined + as a directory containing source files and possibly further sub directories. + After having initially expanded the given location with #globRootdirs, each + directory is examined depth first, until encountering a directory containing + source files, which then yields a result. Especially, this can be used to traverse + an organisational directory structure and find out all possible source trees of + to be built into packages, plugins, individual tool executables etc. + @return: the relative path names of all source root dirs found (generator function). + """ + for dir in globRootdirs(location): + if isSrcDir(dir,patterns): + yield dir + else: + for result in findSrcTrees(str(dir)+'/*'): + yield result + + +def isSrcDir(path, patterns=SRCPATTERNS): + """ helper: investigate the given (relative) path + @param patterns: list of wildcards defining what counts as "source file" + @return: True if it's a directory containing any source file + """ + if not os.path.isdir(path): + return False + else: + for p in patterns: + if glob.glob(path+'/'+p): + return True + + def filterNodes(nlist, removeName=None): """ filter out scons build nodes using the given criteria. @@ -115,6 +147,19 @@ def getDirname(dir): +def createPlugins(env, dir): + """ investigate the given source directory to identify all contained source trees. + @return: a list of build nodes defining a plugin for each of these source trees. + """ + return [env.LoadableModule( '#$PLUGDIR/%s' % getDirname(tree) + , srcSubtree(env, tree) + , SHLIBPREFIX='', SHLIBSUFFIX='.lum' + ) + for tree in findSrcTrees(dir) + ] + + + def checkCommandOption(env, optID, val=None, cmdName=None): """ evaluate and verify an option, which may point at a command. besides specifying a path, the option may read True, yes or 1, 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/common/guifacade.cpp b/src/common/guifacade.cpp index 8b2bf0dee..60a16d0f6 100644 --- a/src/common/guifacade.cpp +++ b/src/common/guifacade.cpp @@ -27,7 +27,6 @@ #include "lib/error.hpp" #include "lib/singleton.hpp" #include "lib/functorutil.hpp" -#include "lib/thread-wrapper.hpp" #include "common/instancehandle.hpp" #include @@ -46,7 +45,6 @@ namespace gui { using util::dispatchSequenced; using lib::Sync; using lib::RecursiveLock_NoWait; - using lib::Thread; @@ -62,7 +60,7 @@ namespace gui { : theGUI_("lumieraorg_Gui", 1, 1, "lumieraorg_GuiStarterPlugin") // load GuiStarterPlugin { ASSERT (theGUI_); - Thread ("GUI-Main", bind (&GuiRunner::kickOff, this, terminationHandle)); + this->kickOff (terminationHandle); if (lumiera_error_peek()) throw lumiera::error::Fatal("failed to bring up GUI",lumiera_error()); diff --git a/src/gui/guistart.cpp b/src/gui/guistart.cpp index 455dafabb..86a8a0ab4 100644 --- a/src/gui/guistart.cpp +++ b/src/gui/guistart.cpp @@ -53,6 +53,7 @@ #include "gui/guifacade.hpp" #include "gui/notification-service.hpp" #include "common/subsys.hpp" +#include "lib/thread-wrapper.hpp" #include "lib/singleton.hpp" extern "C" { @@ -60,11 +61,14 @@ extern "C" { #include "common/interfacedescriptor.h" } +#include #include using std::string; +using lib::Thread; +using std::tr1::bind; using lumiera::Subsys; using gui::LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1); @@ -120,14 +124,19 @@ namespace gui { }; + void + runGUI (Subsys::SigTerm& reportTermination) + { + GuiLifecycle(reportTermination).run(); + } } // (End) impl details void - kickOff (Subsys::SigTerm& reportTermination) + kickOff (Subsys::SigTerm& terminationHandle) { - GuiLifecycle(reportTermination).run(); + Thread ("GUI-Main", bind (&runGUI, terminationHandle)); } } // namespace gui 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/src/tool/Makefile.am b/src/tool/Makefile.am index 64f8fa182..3d5599bdb 100644 --- a/src/tool/Makefile.am +++ b/src/tool/Makefile.am @@ -18,10 +18,19 @@ lumitool_srcdir = $(top_srcdir)/src/tool noinst_PROGRAMS += luidgen - luidgen_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror luidgen_CPPFLAGS = -I$(top_srcdir)/src/ -luidgen_SOURCES = \ - $(lumitool_srcdir)/luidgen.c +luidgen_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl +luidgen_SOURCES = $(lumitool_srcdir)/luidgen.c -luidgen_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl + +noinst_PROGRAMS += vgsuppression +vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror +vgsuppression_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) -ldl liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl +vgsuppression_SOURCES = $(admin_srcdir)/vgsuppression.c + + +noinst_PROGRAMS += rsvg-convert +rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_GUI_CFLAGS) -std=gnu99 -Wall -Werror +rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2 +rsvg_convert_SOURCES = $(admin_srcdir)/rsvg-convert.c diff --git a/src/tool/SConscript b/src/tool/SConscript index 2336c3553..0ca19490d 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -3,12 +3,24 @@ ## SConscript - SCons buildscript for tool subdirectory (called by SConstruct) ## -Import('env','artifacts','core') +Import('env','envGtk','artifacts','core') + +support_lib = artifacts['support'] + +vgsuppr = env.Program('#$BINDIR/vgsuppression','vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +luidgen = env.Program('#$BINDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for rendering SVG icons (uses librsvg) + +rsvg = envGtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') -# build the ubiquitous Hello World application (note: C source) -artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') - + env.Program('#$BINDIR/luidgen', ['luidgen.c']+core) +# build additional test and administrative tools.... +artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') #### hello world (checks C build) + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... + + luidgen + + vgsuppr + + rsvg ] +# Rendering the SVG Icons depends on rsvg-convert +env.Depends(artifacts['icons'], rsvg) + diff --git a/src/tool/hello.c b/src/tool/hello.c index d75f55f94..befad1f21 100644 --- a/src/tool/hello.c +++ b/src/tool/hello.c @@ -7,6 +7,8 @@ int main(int argc, char* argv[]) { - printf("hello lumiera world"); + (void)argc; + (void)argv; + printf("hello lumiera world\n"); return 0; } diff --git a/admin/rsvg-convert.c b/src/tool/rsvg-convert.c similarity index 100% rename from admin/rsvg-convert.c rename to src/tool/rsvg-convert.c diff --git a/admin/vgsuppression.c b/src/tool/vgsuppression.c similarity index 100% rename from admin/vgsuppression.c rename to src/tool/vgsuppression.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 8c9876412..e1f01fc90 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -76,7 +76,7 @@ test_config_LDADD = \ check_LTLIBRARIES += examplepluginc.la -examplepluginc_la_SOURCES = $(tests_srcdir)/plugin/example_plugin.c +examplepluginc_la_SOURCES = $(tests_srcdir)/plugin/examplepluginc/example_plugin.c examplepluginc_la_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -DLUMIERA_PLUGIN -I$(top_srcdir)/src/ examplepluginc_la_LDFLAGS = -module -avoid-version -no-undefined -rpath /dev/null diff --git a/tests/SConscript b/tests/SConscript index a6a4457cd..e914ca001 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -8,12 +8,15 @@ from os import path from Buildhelper import srcSubtree from Buildhelper import scanSubtree from Buildhelper import globRootdirs +from Buildhelper import createPlugins -Import('env','artifacts','core') +Import('env','envPlu','artifacts','core') # temp fix to add test.h -- wouldn't it be better to put this header be into src/lib ? env = env.Clone() env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found +envPlu = envPlu.Clone() +envPlu.Append(CPPPATH='#/.') # temp fix------------- def testExecutable(env,tree, exeName=None, obj=None): @@ -43,39 +46,18 @@ def testCollection(env,dir): return [buildIt(f) for f in scanSubtree(dir,srcpatt)] -def treatPluginTestcase(env): - """ Special case: the test-plugin executable - """ - tree = 'plugin' - env = env.Clone() - env.Append(CPPPATH=tree, CPPDEFINES='LUMIERA_PLUGIN') - prfx = path.join(tree,'example_plugin') - oC = env.SharedObject(prfx, prfx+'.c') - oCPP = env.SharedObject(prfx+'_cpp', prfx+'.cpp') - testplugin = ( env.LoadableModule('#$LIBDIR/examplepluginc', oC, SHLIBPREFIX='') -# + env.SharedLibrary('#$LIBDIR/exampleplugincpp', oCPP, SHLIBPREFIX='') -# doesn't compile yet... - ) - - return testplugin - #-- it depends (at the moment) on a specific isolated test-plugin, - # which is not integrated in the "normal procedure" for building Plugins - # (which is not yet implemented as of 8/07) - # TODO: handle this case automatically -# -# build a Test-Executable out of every subdir... -moduledirs = globRootdirs('*') # but have to treat some subdirs individually. specials = ['plugin','lib','components'] +moduledirs = globRootdirs('*') artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ] - + treatPluginTestcase(env) + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] + + createPlugins(envPlu, 'plugin') ) 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; } diff --git a/tests/plugin/example_plugin.cpp b/tests/plugin/example_plugin.cpp deleted file mode 100644 index aba34b44a..000000000 --- a/tests/plugin/example_plugin.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include - -#include "hello_interface.h" - -class example_plugin -{ -public: - static int myopen(void) - { - std::cout << "opened" << std::endl; - return 0; - } - - static int myclose(void) - { - std::cout << "closed" << std::endl; - return 0; - } -}; - -class example_plugin_de - : public example_plugin -{ -public: - static void hello(void) - { - std::cout << "Hallo Welt!" << std::endl; - } - - static void bye(const char* m) - { - std::cout << "Tschuess " << m << std::endl; - } -}; - - -class example_plugin_en - : public example_plugin -{ -public: - static void hello(void) - { - std::cout << "Hello World!" << std::endl; - } - - static void bye(const char* m) - { - std::cout << "Bye " << m << std::endl; - } -}; - - -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, - example_plugin_de::hello, - example_plugin_de::bye - ); - -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, english, example_plugin_en::myopen, example_plugin_en::myclose, - example_plugin_en::hello, - example_plugin_en::bye - ); diff --git a/tests/plugin/example_plugin.c b/tests/plugin/examplepluginc/example_plugin.c similarity index 100% rename from tests/plugin/example_plugin.c rename to tests/plugin/examplepluginc/example_plugin.c diff --git a/tests/plugin/test-cpp-plugin/example_plugin.cpp b/tests/plugin/test-cpp-plugin/example_plugin.cpp new file mode 100644 index 000000000..b99d951d3 --- /dev/null +++ b/tests/plugin/test-cpp-plugin/example_plugin.cpp @@ -0,0 +1,129 @@ +/* + example_plugin.cpp - example plugin (C++) for testing the interface/plugin system + + Copyright (C) Lumiera.org + 2008, Christian Thaeter , + 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 +#include + +#include "common/interfacedescriptor.h" +#include "common/config_interface.h" + +extern "C" { +#include "common/interface.h" +#include "common/interfacedescriptor.h" + +#include "tests/common/hello_interface.h" +} + +using boost::format; +using std::cout; +using std::endl; + + + +class example_plugin + { + public: + static LumieraInterface + myopen (LumieraInterface self, LumieraInterface interfaces) + { + static format fmt("opened %x global interfaces %x"); + cout << fmt % self % interfaces << endl; + return self; + } + + static void + myclose (LumieraInterface) + { + std::cout << "closed" << endl; + } + }; + + +class example_plugin_de + : public example_plugin + { + public: + static void + griazi () + { + std::cout << "Hallo Welt!" << endl; + } + + static void + servus (const char* m) + { + std::cout << "Tschuess " << m << endl; + } + }; + + +class example_plugin_en + : public example_plugin + { + public: + static void + hello () + { + std::cout << "Hello World!" << endl; + } + + static void + bye (const char* m) + { + std::cout << "Bye " << m << endl; + } + }; + + + + +extern "C" { /* ================== define two lumieraorg_testhello instance ======================= */ + + + + LUMIERA_EXPORT( /* ===================== PLUGIN EXPORTS ================================== */ + + LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0 + ,lumieraorg_hello_german_cpp + , NULL /* no descriptor given */ + , example_plugin::myopen + , example_plugin::myclose + , LUMIERA_INTERFACE_MAP (hello, "\300\244\125\265\235\312\175\263\335\044\371\047\247\263\015\322", + example_plugin_de::griazi) + , LUMIERA_INTERFACE_MAP (goodbye, "\115\365\126\102\201\104\012\257\153\232\006\210\010\346\076\070", + example_plugin_de::servus) + ), + LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0 + ,lumieraorg_hello_english_cpp + , NULL /* no descriptor given */ + , example_plugin::myopen + , example_plugin::myclose + , LUMIERA_INTERFACE_MAP (hello, "\303\367\107\154\077\063\237\066\034\034\050\136\170\220\260\226", + example_plugin_en::hello) + , LUMIERA_INTERFACE_MAP (goodbye, "\107\207\072\105\101\102\150\201\322\043\104\110\232\023\205\161", + example_plugin_en::bye) + ) + ); + +} // extern "C"