Merge branch 'master' of git.lumiera.org:/git/LUMIERA into gui
This commit is contained in:
commit
bf2c1f1e45
46 changed files with 523 additions and 349 deletions
|
|
@ -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
|
||||
|
|
|
|||
41
SConstruct
41
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')
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
# 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.
|
||||
|
||||
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
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ LumieraMMapings
|
|||
lumiera_file_mmapings (LumieraFile self)
|
||||
{
|
||||
if (!self->descriptor->mmapings)
|
||||
LUMIERA_ERROR_SET (file, FILE_NOCHUNKSIZE);
|
||||
LUMIERA_ERROR_SET (file, FILE_NOCHUNKSIZE, lumiera_filedescriptor_name (self->descriptor));
|
||||
|
||||
return self->descriptor->mmapings;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ lumiera_filedescriptor_acquire (const char* name, int flags, LList filenode)
|
|||
INFO (filedescriptor, "try creating dir: %s", dir);
|
||||
if (mkdir (dir, 0777) == -1 && errno != EEXIST)
|
||||
{
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO);
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO, name);
|
||||
goto error;
|
||||
}
|
||||
*slash = '/';
|
||||
|
|
@ -152,14 +152,14 @@ lumiera_filedescriptor_acquire (const char* name, int flags, LList filenode)
|
|||
fd = creat (name, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO);
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO, name);
|
||||
goto error;
|
||||
}
|
||||
close (fd);
|
||||
if (stat (name, &fdesc.stat) != 0)
|
||||
{
|
||||
/* finally, no luck */
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO);
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO, name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ lumiera_filehandle_handle (LumieraFilehandle self)
|
|||
fd = open (lumiera_filedescriptor_name (self->descriptor), lumiera_filedescriptor_flags (self->descriptor) & LUMIERA_FILE_MASK);
|
||||
if (fd == -1)
|
||||
{
|
||||
LUMIERA_ERROR_SET (filehandle, ERRNO);
|
||||
LUMIERA_ERROR_SET (filehandle, ERRNO, lumiera_filedescriptor_name (self->descriptor));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -92,13 +92,13 @@ lumiera_filehandle_handle (LumieraFilehandle self)
|
|||
if (fstat (fd, &st) == -1)
|
||||
{
|
||||
close (fd);
|
||||
LUMIERA_ERROR_SET (filehandle, ERRNO);
|
||||
LUMIERA_ERROR_SET (filehandle, ERRNO, lumiera_filedescriptor_name (self->descriptor));
|
||||
}
|
||||
else if (!lumiera_filedescriptor_samestat (self->descriptor, &st))
|
||||
{
|
||||
close (fd);
|
||||
/* Woops this is not the file we expected to use */
|
||||
LUMIERA_ERROR_SET (filehandle, FILE_CHANGED);
|
||||
LUMIERA_ERROR_SET (filehandle, FILE_CHANGED, lumiera_filedescriptor_name (self->descriptor));
|
||||
}
|
||||
}
|
||||
self->fd = fd;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ lumiera_filehandlecache_handle_acquire (LumieraFilehandlecache self, LumieraFile
|
|||
NOTICE (filehandlecache, "overallocating filehandle");
|
||||
ret = lumiera_filehandle_new (desc);
|
||||
if (!ret)
|
||||
LUMIERA_ERROR_SET (filehandlecache, FILEHANDLECACHE_NOHANDLE);
|
||||
LUMIERA_ERROR_SET (filehandlecache, FILEHANDLECACHE_NOHANDLE, lumiera_filedescriptor_name (desc));
|
||||
else
|
||||
--self->available;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
|
|||
/* extend file (writable) */
|
||||
if (ftruncate (fd, begin+length) == -1)
|
||||
{
|
||||
LUMIERA_ERROR_SET (mmap, ERRNO);
|
||||
LUMIERA_ERROR_SET (mmap, ERRNO, lumiera_filedescriptor_name (file->descriptor));
|
||||
goto etruncate;
|
||||
};
|
||||
descriptor->stat.st_size = begin+length;
|
||||
|
|
@ -173,7 +173,7 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
|
|||
break;
|
||||
|
||||
case GIVE_UP:
|
||||
LUMIERA_ERROR_SET (mmap, MMAP_SPACE);
|
||||
LUMIERA_ERROR_SET (mmap, MMAP_SPACE, lumiera_filedescriptor_name (file->descriptor));
|
||||
goto espace;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -208,12 +208,12 @@ lumiera_config_get (const char* key, const char** value)
|
|||
*value = item->delim+1;
|
||||
}
|
||||
else
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY);
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_SYNTAX_KEY);
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_SYNTAX_KEY, key);
|
||||
}
|
||||
|
||||
return *value;
|
||||
|
|
|
|||
|
|
@ -77,12 +77,12 @@ lumiera_config_number_get (const char* key, long long* value)
|
|||
/* got it, scan it */
|
||||
if (sscanf (raw_value, "%Li", value) != 1)
|
||||
{
|
||||
LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE, lumiera_tmpbuf_snprintf (5000, "key '%s', value '%s'", key, raw_value));
|
||||
raw_value = NULL;
|
||||
LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY);
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ scan_string (const char* in)
|
|||
}
|
||||
else
|
||||
/* quotes doesnt match */
|
||||
LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE);
|
||||
LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE, "unmatched quotes");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -208,7 +208,7 @@ lumiera_config_string_get (const char* key, const char** value)
|
|||
*value = scan_string (raw_value);
|
||||
}
|
||||
else
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY);
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ lumiera_config_wordlist_get (const char* key, const char** value)
|
|||
*value = raw_value;
|
||||
}
|
||||
else
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY);
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key);
|
||||
|
||||
TODO ("remove the ERROR_SET because config_get sets it already? also in all other getters in this file");
|
||||
}
|
||||
|
|
@ -322,7 +322,7 @@ lumiera_config_word_get (const char* key, const char** value)
|
|||
*value = scan_word (raw_value);
|
||||
}
|
||||
else
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY);
|
||||
LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ parse_directive (LumieraConfigitem self, char* itr)
|
|||
self->key = NULL;
|
||||
self->key_size = 0;
|
||||
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX);
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -260,7 +260,7 @@ parse_directive (LumieraConfigitem self, char* itr)
|
|||
self->key = NULL;
|
||||
self->key_size = 0;
|
||||
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX);
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -317,7 +317,7 @@ parse_section (LumieraConfigitem self, char* itr)
|
|||
self->key = NULL;
|
||||
self->key_size = 0;
|
||||
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX);
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -329,7 +329,7 @@ parse_section (LumieraConfigitem self, char* itr)
|
|||
self->key = NULL;
|
||||
self->key_size = 0;
|
||||
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX);
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
@ -368,7 +368,7 @@ parse_configentry (LumieraConfigitem self, char* itr)
|
|||
self->key = NULL;
|
||||
self->key_size = 0;
|
||||
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX);
|
||||
LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
|
|||
|
|
@ -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" {
|
||||
|
|
@ -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 <boost/scoped_ptr.hpp>
|
||||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -283,13 +283,13 @@ lumiera_plugin_register (LumieraPlugin plugin)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_VERSION);
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_VERSION, plugin->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_REGISTER);
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_REGISTER, plugin->name);
|
||||
}
|
||||
}
|
||||
return !!lumiera_error_peek();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "lib/safeclib.h"
|
||||
#include "common/plugin.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
|
@ -42,18 +43,10 @@ lumiera_plugin_load_DYNLIB (const char* name)
|
|||
plugin = (LumieraInterface) dlsym (handle, LUMIERA_INTERFACE_DSTRING (lumieraorg__plugin, 0, lumieraorg_plugin));
|
||||
|
||||
if (!plugin)
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_WTF);
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_WTF, name);
|
||||
}
|
||||
else
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_OPEN);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (lumiera_error_peek())
|
||||
{
|
||||
const char* problem = dlerror();
|
||||
WARN_IF (problem, plugin, "Problem opening shared object %s : %s", name, problem);
|
||||
}
|
||||
#endif
|
||||
LUMIERA_ERROR_SET (plugin, PLUGIN_OPEN, lumiera_tmpbuf_snprintf (4096, "%s: %s", name, dlerror()));
|
||||
|
||||
return lumiera_plugin_init (self, handle, plugin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <tr1/functional>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ namespace gui {
|
|||
, LUMIERA_INTERFACE_INLINE (displayInfo, "\366\075\213\163\207\040\221\233\010\366\174\374\317\126\331\205",
|
||||
void, (const char* text),
|
||||
{
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE);
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, text);
|
||||
else
|
||||
_instance->displayInfo(text);
|
||||
}
|
||||
|
|
@ -155,7 +155,7 @@ namespace gui {
|
|||
, LUMIERA_INTERFACE_INLINE (triggerGuiShutdown, "\267\043\244\065\107\314\370\175\063\330\264\257\302\146\326\303",
|
||||
void, (const char* cause),
|
||||
{
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE);
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cause);
|
||||
else
|
||||
_instance->triggerGuiShutdown(cause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -33,51 +33,103 @@
|
|||
predefined errors
|
||||
*/
|
||||
LUMIERA_ERROR_DEFINE (ERRNO, "errno");
|
||||
LUMIERA_ERROR_DEFINE (EERROR, "could not initialize error system");
|
||||
|
||||
|
||||
/* Thread local storage */
|
||||
static pthread_key_t lumiera_error_tls;
|
||||
static pthread_once_t lumiera_error_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
/**
|
||||
* Holding error and some context data.
|
||||
*/
|
||||
struct lumiera_errorcontext_struct
|
||||
{
|
||||
lumiera_err err;
|
||||
char* extra;
|
||||
};
|
||||
|
||||
typedef struct lumiera_errorcontext_struct lumiera_errorcontext;
|
||||
typedef lumiera_errorcontext* LumieraErrorcontext;
|
||||
|
||||
|
||||
static void
|
||||
lumiera_error_tls_delete (void* err)
|
||||
{
|
||||
if (err)
|
||||
free (((LumieraErrorcontext)err)->extra);
|
||||
}
|
||||
|
||||
static void
|
||||
lumiera_error_tls_init (void)
|
||||
{
|
||||
pthread_key_create (&lumiera_error_tls, NULL);
|
||||
if (!!pthread_key_create (&lumiera_error_tls, lumiera_error_tls_delete))
|
||||
LUMIERA_DIE (EERROR);
|
||||
}
|
||||
|
||||
|
||||
lumiera_err
|
||||
lumiera_error_set (lumiera_err nerr)
|
||||
LumieraErrorcontext
|
||||
lumiera_error_get (void)
|
||||
{
|
||||
if (lumiera_error_initialized == PTHREAD_ONCE_INIT)
|
||||
pthread_once (&lumiera_error_initialized, lumiera_error_tls_init);
|
||||
|
||||
lumiera_err err = pthread_getspecific (lumiera_error_tls);
|
||||
if (!err)
|
||||
pthread_setspecific (lumiera_error_tls, nerr);
|
||||
LumieraErrorcontext self = pthread_getspecific (lumiera_error_tls);
|
||||
if (!self)
|
||||
{
|
||||
/* malloc() and not lumiera_malloc() here because nothing else might be initialized when calling this */
|
||||
self = malloc (sizeof *self);
|
||||
if (!self)
|
||||
LUMIERA_DIE (EERROR);
|
||||
|
||||
return err;
|
||||
self->err = NULL;
|
||||
self->extra = NULL;
|
||||
pthread_setspecific (lumiera_error_tls, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
lumiera_err
|
||||
lumiera_error_set (lumiera_err nerr, const char* extra)
|
||||
{
|
||||
LumieraErrorcontext self = lumiera_error_get ();
|
||||
|
||||
if (!self->err)
|
||||
{
|
||||
self->err = nerr;
|
||||
free (self->extra);
|
||||
if (extra)
|
||||
self->extra = strdup (extra);
|
||||
else
|
||||
self->extra = NULL;
|
||||
}
|
||||
|
||||
return self->err;
|
||||
}
|
||||
|
||||
|
||||
lumiera_err
|
||||
lumiera_error (void)
|
||||
{
|
||||
if (lumiera_error_initialized == PTHREAD_ONCE_INIT)
|
||||
pthread_once (&lumiera_error_initialized, lumiera_error_tls_init);
|
||||
LumieraErrorcontext self = lumiera_error_get ();
|
||||
lumiera_err err = self->err;
|
||||
|
||||
lumiera_err err = pthread_getspecific (lumiera_error_tls);
|
||||
if (err)
|
||||
pthread_setspecific (lumiera_error_tls, NULL);
|
||||
self->err = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
const char*
|
||||
lumiera_error_extra (void)
|
||||
{
|
||||
return lumiera_error_get ()->extra;
|
||||
}
|
||||
|
||||
|
||||
lumiera_err
|
||||
lumiera_error_peek (void)
|
||||
{
|
||||
if (lumiera_error_initialized == PTHREAD_ONCE_INIT)
|
||||
pthread_once (&lumiera_error_initialized, lumiera_error_tls_init);
|
||||
|
||||
return pthread_getspecific (lumiera_error_tls);
|
||||
return lumiera_error_get ()->err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,19 +67,30 @@ lumiera_err LUMIERA_ERROR_##err = "LUMIERA_ERROR_" #err ":" msg
|
|||
* @param flag NoBug flag describing the subsystem where the error was raised
|
||||
* @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY)
|
||||
*/
|
||||
#define LUMIERA_ERROR_SET(flag, err) \
|
||||
(({ERROR (flag, "%s", strchr(LUMIERA_ERROR_##err, ':')+1);}), \
|
||||
lumiera_error_set(LUMIERA_ERROR_##err))
|
||||
#define LUMIERA_ERROR_SET(flag, err, extra) \
|
||||
do { \
|
||||
const char* theextra = extra; \
|
||||
ERROR (flag, "%s%s%s", strchr(LUMIERA_ERROR_##err, ':')+1, theextra?": ":"", theextra?theextra:""); \
|
||||
lumiera_error_set(LUMIERA_ERROR_##err, theextra); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Set error state for the current thread.
|
||||
* If the error state of the current thread was cleared, then set it, else preserve the old state.
|
||||
* @param nerr name of the error with 'LUMIERA_ERROR_' prefix (example: LUMIERA_ERROR_NO_MEMORY)
|
||||
* @return old state, that is NULL for success, when the state was cleared and a pointer to a pending
|
||||
* @param extra a string (possibly a constructed tmpbuf) which adds some more context to the error occured this will be copied
|
||||
* @return old state, that is NULL for success, when the state was cleared and a pointer to a pending
|
||||
* error when the error state was already set
|
||||
*/
|
||||
lumiera_err
|
||||
lumiera_error_set (lumiera_err err);
|
||||
lumiera_error_set (lumiera_err nerr, const char* extra);
|
||||
|
||||
/**
|
||||
* Query the extra context for the last error
|
||||
* @return the extra string from the last error
|
||||
*/
|
||||
const char*
|
||||
lumiera_error_extra (void);
|
||||
|
||||
/**
|
||||
* Get and clear current error state.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace lumiera {
|
|||
desc_ (description),
|
||||
cause_ ("")
|
||||
{
|
||||
lumiera_error_set (this->id_);
|
||||
lumiera_error_set (this->id_, description.c_str ());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ namespace lumiera {
|
|||
desc_ (description),
|
||||
cause_ (extractCauseMsg(cause))
|
||||
{
|
||||
lumiera_error_set (this->id_);
|
||||
lumiera_error_set (this->id_, description.c_str ());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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 = $(lumitool_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 = $(lumitool_srcdir)/rsvg-convert.c
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export LUMIERA_PLUGIN_PATH=.libs
|
|||
export LUMIERA_CONFIG_PATH=./
|
||||
|
||||
TEST "discovering plugins" plugin_discover <<END
|
||||
out: found plugin: .libs/examplepluginc.so
|
||||
out: found plugin: .libs/examplepluginc.lum
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ TEST ("plugin_discover")
|
|||
|
||||
if (lumiera_plugin_discover (lumiera_plugin_load, lumiera_plugin_register))
|
||||
{
|
||||
LumieraPlugin p = lumiera_plugin_lookup (".libs/examplepluginc.so");
|
||||
LumieraPlugin p = lumiera_plugin_lookup (".libs/examplepluginc.lum");
|
||||
printf ("found plugin: %s\n", lumiera_plugin_name (p));
|
||||
lumiera_plugin_discover (lumiera_plugin_load, lumiera_plugin_register);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ main (int argc, char** argv)
|
|||
|
||||
if (!strcmp(argv[1], "set"))
|
||||
{
|
||||
lumiera_error_set (LUMIERA_ERROR_TEST);
|
||||
lumiera_error_set (LUMIERA_ERROR_TEST, NULL);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "get_no"))
|
||||
|
|
@ -47,7 +47,7 @@ main (int argc, char** argv)
|
|||
|
||||
if (!strcmp(argv[1], "get"))
|
||||
{
|
||||
lumiera_error_set (LUMIERA_ERROR_TEST);
|
||||
lumiera_error_set (LUMIERA_ERROR_TEST, NULL);
|
||||
const char* err;
|
||||
err = lumiera_error ();
|
||||
printf ("%s\n", err);
|
||||
|
|
@ -55,7 +55,7 @@ main (int argc, char** argv)
|
|||
|
||||
if (!strcmp(argv[1], "get2"))
|
||||
{
|
||||
lumiera_error_set (LUMIERA_ERROR_TEST);
|
||||
lumiera_error_set (LUMIERA_ERROR_TEST, NULL);
|
||||
const char* err;
|
||||
err = lumiera_error ();
|
||||
printf ("%s\n", err);
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
#include <iostream>
|
||||
|
||||
#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
|
||||
);
|
||||
129
tests/plugin/test-cpp-plugin/example_plugin.cpp
Normal file
129
tests/plugin/test-cpp-plugin/example_plugin.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
example_plugin.cpp - example plugin (C++) for testing the interface/plugin system
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>,
|
||||
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 <iostream>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#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"
|
||||
Loading…
Reference in a new issue