diff --git a/.gitignore b/.gitignore index 10dbaee23..69cb7933a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,11 @@ *~ *.tar.* .[^.]* +*.o *.os *.gch ,valgrind.log* -admin/scons/*.pyc +*.pyc optcache Makefile.in build/* @@ -13,5 +14,6 @@ bin/* autom4te.cache/* scripts/* configure +config.log aclocal.m4 semantic.cache diff --git a/SConstruct b/SConstruct index c5f2971ee..2b3e2cfd0 100644 --- a/SConstruct +++ b/SConstruct @@ -21,13 +21,6 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ##################################################################### -import sys -sys.path.append("./admin/scons") - -import os -from Buildhelper import * -from LumieraEnvironment import * - #-----------------------------------Configuration OPTIONSCACHEFILE = 'optcache' @@ -37,6 +30,8 @@ BINDIR = 'bin' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' +TOOLDIR = './admin/scons' +SVGRENDERER = 'admin/render-icon' #-----------------------------------Configuration # NOTE: scons -h for help. @@ -46,6 +41,14 @@ VERSION = '0.1+pre.01' +import os +import sys + +sys.path.append(TOOLDIR) + +from Buildhelper import * +from LumieraEnvironment import * + ##################################################################### @@ -56,7 +59,10 @@ def setupBasicEnvironment(): EnsureSConsVersion(0,96,90) opts = defineCmdlineOptions() - env = LumieraEnvironment(options=opts) + env = LumieraEnvironment(options=opts + ,toolpath = [TOOLDIR] + ,tools = ["default", "BuilderGCH", "BuilderDoxygen"] + ) env.Append ( CCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honor CFLAGS, only CCFLAGS env.Replace( VERSION=VERSION @@ -68,7 +74,7 @@ def setupBasicEnvironment(): , CCFLAGS='-Wall ' # -fdiagnostics-show-option ) - RegisterPrecompiledHeader_Builder(env) + RegisterIcon_Builder(env,SVGRENDERER) handleNoBugSwitches(env) env.Append(CPPDEFINES = '_GNU_SOURCE') @@ -101,8 +107,7 @@ def handleNoBugSwitches(env): level = env['BUILDLEVEL'] if level in ['ALPHA', 'BETA']: if not env['DEBUG']: - print 'NoBug: ALPHA or BETA builds without DEBUG not possible, exiting.' - Exit(1) + print 'Warning: NoBug ALPHA or BETA builds requires DEBUG=yes, switching DEBUG on!' env.Replace( DEBUG = 1 ) env.Append(CPPDEFINES = 'EBUG_'+level) elif level == 'RELEASE': @@ -168,24 +173,21 @@ def configurePlatform(env): # run all configuration checks in the given env # Perform checks for prerequisites -------------------------------------------- + problems = [] if not conf.TryAction('pkg-config --version > $TARGET')[0]: - print 'We need pkg-config for including library configurations, exiting.' - Exit(1) + problems.append('We need pkg-config for including library configurations, exiting.') if not conf.CheckLibWithHeader('m', 'math.h','C'): - print 'Did not find math.h / libm, exiting.' - Exit(1) + problems.append('Did not find math.h / libm.') if not conf.CheckLibWithHeader('dl', 'dlfcn.h', 'C'): - print 'Functions for runtime dynamic loading not available, exiting.' - Exit(1) + problems.append('Functions for runtime dynamic loading not available.') if not conf.CheckLibWithHeader('nobugmt', 'nobug.h', 'C'): - print 'Did not find NoBug [http://www.pipapo.org/pipawiki/NoBug], exiting.' - Exit(1) + problems.append('Did not find NoBug [http://www.pipapo.org/pipawiki/NoBug].') if not conf.CheckLibWithHeader('pthread', 'pthread.h', 'C'): - print 'Did not find the pthread lib or pthread.h, exiting.' + problems.append('Did not find the pthread lib or pthread.h.') else: conf.env.Append(CPPFLAGS = ' -DHAVE_PTHREAD') conf.env.Append(CCFLAGS = ' -pthread') @@ -197,49 +199,56 @@ def configurePlatform(env): conf.env.Append(CPPFLAGS = ' -DHAS_VALGRIND_VALGIND_H') if not conf.CheckCXXHeader('tr1/memory'): - print 'We rely on the std::tr1 proposed standard extension for shared_ptr.' - Exit(1) + problems.append('We rely on the std::tr1 proposed standard extension for shared_ptr.') if not conf.CheckCXXHeader('boost/config.hpp'): - print 'We need the C++ boost-lib.' - Exit(1) + problems.append('We need the C++ boost-lib.') else: if not conf.CheckCXXHeader('boost/shared_ptr.hpp'): - print 'We need boost::shared_ptr (shared_ptr.hpp).' - Exit(1) + problems.append('We need boost::shared_ptr (shared_ptr.hpp).') if not conf.CheckLibWithHeader('boost_program_options-mt','boost/program_options.hpp','C++'): - print 'We need boost::program_options (including binary lib for linking).' - Exit(1) + problems.append('We need boost::program_options (including binary lib for linking).') if not conf.CheckLibWithHeader('boost_regex-mt','boost/regex.hpp','C++'): - print 'We need the boost regular expression lib (incl. binary lib for linking).' - Exit(1) + problems.append('We need the boost regular expression lib (incl. binary lib for linking).') # if not conf.CheckLibWithHeader('gavl', ['gavlconfig.h', 'gavl/gavl.h'], 'C'): if not conf.CheckPkgConfig('gavl', 1.0): - print 'Did not find Gmerlin Audio Video Lib [http://gmerlin.sourceforge.net/gavl.html], exiting.' - Exit(1) + problems.append('Did not find Gmerlin Audio Video Lib [http://gmerlin.sourceforge.net/gavl.html].') else: conf.env.mergeConf('gavl') if not conf.CheckPkgConfig('gtkmm-2.4', 2.8): - print 'Unable to configure GTK--, exiting.' - Exit(1) + problems.append('Unable to configure GTK--, exiting.') + + if not conf.CheckPkgConfig('glibmm-2.4', '2.16'): + problems.append('Unable to configure Lib glib--, exiting.') if not conf.CheckPkgConfig('cairomm-1.0', 0.6): - print 'Unable to configure Cairo--, exiting.' - Exit(1) + problems.append('Unable to configure Cairo--, exiting.') if not conf.CheckPkgConfig('gdl-1.0', '0.6.1'): - print 'Unable to configure the GNOME DevTool Library, exiting.' - Exit(1) + problems.append('Unable to configure the GNOME DevTool Library, exiting.') - if not conf.CheckPkgConfig('xv'): Exit(1) + if not conf.CheckPkgConfig('librsvg-2.0', '2.18.1'): + problems.append('Need rsvg Library for rendering icons.') + + if not conf.CheckPkgConfig('xv'): problems.append('Need lib xv') # if not conf.CheckPkgConfig('xext'): Exit(1) # if not conf.CheckPkgConfig('sm'): Exit(1) # # obviously not needed? + + # report missing dependencies + if problems: + print "*** unable to build due to the following problems:" + for isue in problems: + print " * %s" % isue + print + print "build aborted." + Exit(1) + print "** Gathered Library Info: %s" % conf.env.libInfo.keys() @@ -269,6 +278,10 @@ def defineBuildTargets(env, artifacts): setup sub-environments with special build options if necessary. We use a custom function to declare a whole tree of srcfiles. """ + # use PCH to speed up building +# env['GCH'] = ( env.PrecompiledHeader('$SRCDIR/pre.hpp') +# + env.PrecompiledHeader('$SRCDIR/pre_a.hpp') +# ) objback = srcSubtree(env,'$SRCDIR/backend') objproc = srcSubtree(env,'$SRCDIR/proc') @@ -281,27 +294,29 @@ def defineBuildTargets(env, artifacts): + env.StaticLibrary('$BINDIR/lumi.la', objlib) ) - # use PCH to speed up building - precomp = ( env.PrecompiledHeader('$SRCDIR/pre') - + env.PrecompiledHeader('$SRCDIR/pre_a') - ) - env.Depends(objproc, precomp) - env.Depends(objlib, precomp) artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/main.cpp']+ core ) artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', objplug) - + # the Lumiera GTK GUI - envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','xv','xext','sm']) + envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm']) objgui = srcSubtree(envgtk,'$SRCDIR/gui') + # render and install Icons + vector_icon_dir = env.subst('$ICONDIR/svg') + prerendered_icon_dir = env.subst('$ICONDIR/prerendered') + artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] + + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] + ) + artifacts['lumigui'] = ( envgtk.Program('$BINDIR/lumigui', objgui + core) - + env.Install('$BINDIR', env.Glob('$ICONDIR/*.png')) + 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') @@ -321,16 +336,9 @@ def definePostBuildTargets(env, artifacts): env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ]) env.Clean ('build', [ '$SRCDIR/pre.gch' ]) - # Doxygen documentation - # Note: at the moment we only depend on Doxyfile - # obviousely, we should depend on all sourcefiles - # real Doxygen builder for scons is under developement for 0.97 - # so for the moment I prefere not to bother - doxyfile = File('doc/devel/Doxyfile') - env.NoClean(doxyfile) - doxydoc = artifacts['doxydoc'] = [ Dir('doc/devel/html'), Dir('doc/devel/latex') ] - env.Command(doxydoc, doxyfile, "doxygen Doxyfile 2>&1 |tee ,doxylog", chdir='doc/devel') - env.Clean ('doc/devel', doxydoc + ['doc/devel/,doxylog']) + doxydoc = artifacts['doxydoc'] = env.Doxygen('doc/devel/Doxyfile') + env.Alias ('doxydoc', doxydoc) + env.Clean ('doxydoc', doxydoc + ['doc/devel/,doxylog','doc/devel/warnings.txt']) def defineInstallTargets(env, artifacts): diff --git a/admin/SConscript b/admin/SConscript new file mode 100644 index 000000000..d0ad7b84e --- /dev/null +++ b/admin/SConscript @@ -0,0 +1,17 @@ +# -*- 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 supressing 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/render-icon.py b/admin/render-icon.py index ac8ab2453..26bdb3653 100755 --- a/admin/render-icon.py +++ b/admin/render-icon.py @@ -68,7 +68,7 @@ def parsePlateLayer( layer ): return rectangles def parseSVG( file_path ): - print "Rendering " + file_path + print "Parsing " + file_path svgdoc = minidom.parse(file_path) for root_node in svgdoc.childNodes: if root_node.nodeType == minidom.Node.ELEMENT_NODE: @@ -104,6 +104,9 @@ def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size): # Prepare a Cairo context width = int(rectangle[2]) height = int(rectangle[3]) + + if not os.path.exists(rsvgPath): + print "Error: executable %s not found." % rsvgPath os.spawnlp(os.P_WAIT, rsvgPath, rsvgPath, "--source-rect=%g:%g:%g:%g" % (rectangle[0], rectangle[1], rectangle[2], rectangle[3]), @@ -115,6 +118,13 @@ def renderSvgIcon(file_path, out_dir): for rectangle in rectangles: renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size) +def getTargetNames(file_path): + """get a list of target names to be rendered from the given source SVG + usable to setup the build targets for SCons + """ + artwork_name, _ , rectangles = parseSVG(file_path) + return ["%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name) for rectangle in rectangles ] + #def renderSvgIcons(): # listing = os.listdir(svgDir) # for file_path in listing: @@ -129,7 +139,8 @@ def renderSvgIcon(file_path, out_dir): # copyMergeDirectory(src_dir, list_item) def printHelp(): - print "render-icon.py - An icon rendering utility script for lumiera" + print "render-icon.py SRCFILE.svg TARGETDIR" + print "An icon rendering utility script for lumiera" def parseArguments(argv): optlist, args = getopt.getopt(argv, "") diff --git a/admin/scons/BuilderDoxygen.py b/admin/scons/BuilderDoxygen.py new file mode 100644 index 000000000..943fce946 --- /dev/null +++ b/admin/scons/BuilderDoxygen.py @@ -0,0 +1,230 @@ +# -*- python -*- +## +## BuilderDoxygen.py - SCons builder for generating Doxygen documentation +## + +# +# Astxx, the Asterisk C++ API and Utility Library. +# Copyright (C) 2005, 2006 Matthew A. Nicholson +# Copyright (C) 2006 Tim Blechmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see http://www.gnu.org/licenses/ +##################################################################### + +# history: 8/2008 adapted for Lumiera build system +# added patch for Doxyfile in subdirectory +# see http://www.scons.org/wiki/DoxygenBuilder + + +import os +import os.path +import glob +from fnmatch import fnmatch + + +def DoxyfileParse(file_contents): + """ + Parse a Doxygen source file and return a dictionary of all the values. + Values will be strings and lists of strings. + """ + data = {} + + import shlex + lex = shlex.shlex(instream = file_contents, posix = True) + lex.wordchars += "*+./-:" + lex.whitespace = lex.whitespace.replace("\n", "") + lex.escape = "" + + lineno = lex.lineno + token = lex.get_token() + key = token # the first token should be a key + last_token = "" + key_token = False + next_key = False + new_data = True + + def append_data(data, key, new_data, token): + if new_data or len(data[key]) == 0: + data[key].append(token) + else: + data[key][-1] += token + + while token: + if token in ['\n']: + if last_token not in ['\\']: + key_token = True + elif token in ['\\']: + pass + elif key_token: + key = token + key_token = False + else: + if token == "+=": + if not data.has_key(key): + data[key] = list() + elif token == "=": + data[key] = list() + else: + append_data( data, key, new_data, token ) + new_data = True + + last_token = token + token = lex.get_token() + + if last_token == '\\' and token != '\n': + new_data = False + append_data( data, key, new_data, '\\' ) + + # compress lists of len 1 into single strings + for (k, v) in data.items(): + if len(v) == 0: + data.pop(k) + + # items in the following list will be kept as lists and not converted to strings + if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]: + continue + + if len(v) == 1: + data[k] = v[0] + + return data + +def DoxySourceScan(node, env, path): + """ + Doxygen Doxyfile source scanner. This should scan the Doxygen file and add + any files used to generate docs to the list of source files. + """ + default_file_patterns = [ + '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx', + '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++', + '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm', + '*.py', + ] + + default_exclude_patterns = [ + '*~', + ] + + sources = [] + + data = DoxyfileParse(node.get_contents()) + + if data.get("RECURSIVE", "NO") == "YES": + recursive = True + else: + recursive = False + + file_patterns = data.get("FILE_PATTERNS", default_file_patterns) + exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) + + # + # We're running in the top-level directory, but the doxygen + # configuration file is in the same directory as node; this means + # that relative pathnames in node must be adjusted before they can + # go onto the sources list + conf_dir = os.path.dirname(str(node)) + + for node in data.get("INPUT", []): + if not os.path.isabs(node): + node = os.path.join(conf_dir, node) + if os.path.isfile(node): + sources.append(node) + elif os.path.isdir(node): + if recursive: + for root, dirs, files in os.walk(node): + for f in files: + filename = os.path.join(root, f) + + pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False) + exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True) + + if pattern_check and not exclude_check: + sources.append(filename) + else: + for pattern in file_patterns: + sources.extend(glob.glob("/".join([node, pattern]))) + + sources = map( lambda path: env.File(path), sources ) + return sources + + +def DoxySourceScanCheck(node, env): + """Check if we should scan this file""" + return os.path.isfile(node.path) + +def DoxyEmitter(source, target, env): + """Doxygen Doxyfile emitter""" + # possible output formats and their default values and output locations + output_formats = { + "HTML": ("YES", "html"), + "LATEX": ("YES", "latex"), + "RTF": ("NO", "rtf"), + "MAN": ("NO", "man"), + "XML": ("NO", "xml"), + } + + data = DoxyfileParse(source[0].get_contents()) + + targets = [] + out_dir = data.get("OUTPUT_DIRECTORY", ".") + + # add our output locations + for (k, v) in output_formats.items(): + if data.get("GENERATE_" + k, v[0]) == "YES": + targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) + + # don't clobber targets + for node in targets: + env.Precious(node) + + # set up cleaning stuff + for node in targets: + env.Clean(node, node) + + return (targets, source) + + +def generate(env): + """ + Add builders and construction variables for the + Doxygen tool. This is currently for Doxygen 1.4.6. + """ + doxyfile_scanner = env.Scanner( + DoxySourceScan, + "DoxySourceScan", + scan_check = DoxySourceScanCheck, + ) + + import SCons.Builder + doxyfile_builder = SCons.Builder.Builder( + action = "cd ${SOURCE.dir} && (${DOXYGEN} ${SOURCE.file} 2>&1 |tee ,doxylog)", + emitter = DoxyEmitter, + target_factory = env.fs.Entry, + single_source = True, + source_scanner = doxyfile_scanner, + ) + + env.Append(BUILDERS = { + 'Doxygen': doxyfile_builder, + }) + + env.AppendUnique( + DOXYGEN = 'doxygen', + ) + +def exists(env): + """ + Make sure doxygen exists. + """ + return env.Detect("doxygen") + diff --git a/admin/scons/BuilderGCH.py b/admin/scons/BuilderGCH.py new file mode 100644 index 000000000..c522cb9cd --- /dev/null +++ b/admin/scons/BuilderGCH.py @@ -0,0 +1,110 @@ +# -*- python -*- +## +## BuilderGCH.py - SCons builder for gcc's precompiled headers +## + +# Copyright (C) scons.org/wiki/GchBuilder +# 2006 Tim Blechmann +# 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, see http://www.gnu.org/licenses/ +##################################################################### + +# history: 8/2008 adapted for Lumiera build system +# changed to accept a list of precompiled header defs + + +from types import ListType + +import SCons.Action +import SCons.Builder +import SCons.Scanner.C +import SCons.Util +import SCons.Script + +SCons.Script.EnsureSConsVersion(0,96,92) + +GchAction = SCons.Action.Action('$GCHCOM', '$GCHCOMSTR') +GchShAction = SCons.Action.Action('$GCHSHCOM', '$GCHSHCOMSTR') + +def gen_suffix(env, sources): + return sources[0].get_suffix() + env['GCHSUFFIX'] + + +GchShBuilder = SCons.Builder.Builder(action = GchShAction, + source_scanner = SCons.Scanner.C.CScanner(), + suffix = gen_suffix) + +GchBuilder = SCons.Builder.Builder(action = GchAction, + source_scanner = SCons.Scanner.C.CScanner(), + suffix = gen_suffix) + +def setup_dependency(target,source,env, key): + scanner = SCons.Scanner.C.CScanner() + path = scanner.path(env) + deps = scanner(source[0], env, path) + + if env.has_key(key) and env[key]: + for header in env[key]: + header_path = header.path.strip('.gch') + if header_path in [x.path for x in deps]: + print "Precompiled header(%s) %s \t <--- %s" % (key,header_path,source[0]) + env.Depends(target, header) + + +def static_pch_emitter(target,source,env): + SCons.Defaults.StaticObjectEmitter( target, source, env ) + setup_dependency(target,source,env, key='GCH') + return (target, source) + +def shared_pch_emitter(target,source,env): + SCons.Defaults.SharedObjectEmitter( target, source, env ) + setup_dependency(target,source,env, key='GCH-sh') + return (target, source) + +def generate(env): + """ + Add builders and construction variables for the Gch builder. + """ + env.Append(BUILDERS = { + 'gch': env.Builder( + action = GchAction, + target_factory = env.fs.File, + ), + 'gchsh': env.Builder( + action = GchShAction, + target_factory = env.fs.File, + ), + }) + + try: + bld = env['BUILDERS']['GCH'] + bldsh = env['BUILDERS']['GCH-sh'] + except KeyError: + bld = GchBuilder + bldsh = GchShBuilder + env['BUILDERS']['PrecompiledHeader'] = bld + env['BUILDERS']['PrecompiledHeaderShared'] = bldsh + + env['GCHCOM'] = '$CXX -o $TARGET -x c++-header -c $CXXFLAGS $_CCCOMCOM $SOURCE' + env['GCHSHCOM'] = '$CXX -o $TARGET -x c++-header -c $SHCXXFLAGS $_CCCOMCOM $SOURCE' + env['GCHSUFFIX'] = '.gch' + + for suffix in SCons.Util.Split('.c .C .cc .cxx .cpp .c++'): + env['BUILDERS']['StaticObject'].add_emitter( suffix, static_pch_emitter ) + env['BUILDERS']['SharedObject'].add_emitter( suffix, shared_pch_emitter ) + + +def exists(env): + return env.Detect('g++') diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 02f17b2b4..38940424c 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -28,6 +28,8 @@ import fnmatch import re import tarfile +from SCons.Action import Action + # @@ -58,13 +60,13 @@ def srcSubtree(env,tree,isShared=False,builder=None, **args): else: builder = lambda f: env.Object(f, **args) - return [builder(f) for f in scanSrcSubtree(root)] + return [builder(f) for f in scanSubtree(root)] SRCPATTERNS = ['*.c','*.cpp','*.cc'] -def scanSrcSubtree(roots): +def scanSubtree(roots, patterns=SRCPATTERNS): """ first expand (possible) wildcards and filter out non-dirs. Then scan the given subtree for source filesnames (python generator function) @@ -73,7 +75,7 @@ def scanSrcSubtree(roots): for (dir,_,files) in os.walk(root): if dir.startswith('./'): dir = dir[2:] - for p in SRCPATTERNS: + for p in patterns: for f in fnmatch.filter(files, p): yield os.path.join(dir,f) @@ -102,22 +104,50 @@ def filterNodes(nlist, removeName=None): return filter(predicate, nlist) -def RegisterPrecompiledHeader_Builder(env): - """ Registeres an Custom Builder for generating a precompiled Header. - Note you should define a dependency to the PCH file - """ - def genCmdline(source, target, env, for_signature): - return '$CXXCOM -x c++-header %s' % source[0] - def fixSourceDependency(target, source, env): - print "precompiled header: %s --> %s" % (source[0],target[0]) - return (target, source) + +def getDirname(dir): + """ extract directory name without leading path """ + dir = os.path.realpath(dir) + if not os.path.isdir(dir): + dir,_ = os.path.split(dir) + _, name = os.path.split(dir) + return name - gchBuilder = env.Builder( generator = genCmdline - , emitter = fixSourceDependency - , suffix = '.gch' - , src_suffix = '.hpp' - ) - env.Append(BUILDERS = {'PrecompiledHeader' : gchBuilder}) + + +def RegisterIcon_Builder(env, renderer): + """ Registeres Custom Builders for generating and installing Icons. + Additionally you need to build the tool (rsvg-convert.c) + used to generate png from the svg source using librsvg. + """ + renderer = __import__(renderer) # load python script for invoking the render + renderer.rsvgPath = env.subst("$BINDIR/rsvg-convert") + + def invokeRenderer(target, source, env): + source = str(source[0]) + targetdir = env.subst("$BINDIR") + renderer.main([source,targetdir]) + return 0 + + def createIconTargets(target,source,env): + """ parse the SVG to get the target file names """ + source = str(source[0]) + targetdir = os.path.basename(str(target[0])) + targetfiles = renderer.getTargetNames(source) # parse SVG + return (["$BINDIR/%s" % name for name in targetfiles], source) + + def IconCopy(env, source): + """Copy icon to corresponding icon dir. """ + subdir = getDirname(source) + return env.Install("$BINDIR/%s" % subdir, source) + + + buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") + , single_source = True + , emitter = createIconTargets + ) + env.Append(BUILDERS = {'IconRender' : buildIcon}) + env.AddMethod(IconCopy) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 82d419a65..2d8f1bb01 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -22,7 +22,8 @@ ##################################################################### -from SCons.SConf import SConf +import SCons +import SCons.SConf from SCons.Environment import Environment from Buildhelper import * @@ -77,17 +78,34 @@ class LumieraEnvironment(Environment): return libInfo def Glob (self, pattern): - """ temporary workaround; newer versions of SCons provide this as a global function - """ + """ temporary workaround; newer versions of SCons provide this as a global function """ pattern = self.subst(pattern) return glob.glob(pattern) + + def AddMethod (self, function): + """ temporary workaround; newer versions of SCons provide this as a global function """ + self.__dict__[function.__name__] = function.__get__(self) + + +#### temporary pre 1.0 SCons compatibility hack #### +_ver = map(int, SCons.__version__.split('.')) +_old = (_ver[0]<1 and _ver[1]<98) +if _old: + ConfigBase = SCons.SConf.SConf +else: + ConfigBase = SCons.SConf.SConfBase + del LumieraEnvironment.Glob + del LumieraEnvironment.AddMethod + # use the official impl present since SCons 0.98 + # use the new name of the config context base class -class LumieraConfigContext(SConf): + +class LumieraConfigContext(ConfigBase): """ Extends the SCons Configure context with some convenience methods """ def __init__(self, *args,**kw): - SConf.__init__(self,*args,**kw) + ConfigBase.__init__(self,*args,**kw) def CheckPkgConfig (self, libID, minVersion=0): print "Checking for library configuration: %s " % libID diff --git a/doc/devel/.gitignore b/doc/devel/.gitignore new file mode 100644 index 000000000..d6d649abd --- /dev/null +++ b/doc/devel/.gitignore @@ -0,0 +1,3 @@ +,doxylog +warnings.txt +html/* diff --git a/doc/devel/Doxyfile b/doc/devel/Doxyfile index 28bab1f05..b7c59fa54 100644 --- a/doc/devel/Doxyfile +++ b/doc/devel/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = Lumiera -PROJECT_NUMBER = 3.0+alpha +PROJECT_NUMBER = 0.1+pre OUTPUT_DIRECTORY = CREATE_SUBDIRS = YES OUTPUT_LANGUAGE = English @@ -32,7 +32,7 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO +DETAILS_AT_TOP = YES INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 @@ -65,8 +65,8 @@ CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES @@ -179,7 +179,7 @@ HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_FEEDNAME = "Lumiera Doxygen docs" DOCSET_BUNDLE_ID = org.doxygen.Project HTML_DYNAMIC_SECTIONS = NO CHM_FILE = diff --git a/doc/devel/draw/high-level-model.svg b/doc/devel/draw/high-level-model.svg new file mode 100644 index 000000000..f5f0af8e5 --- /dev/null +++ b/doc/devel/draw/high-level-model.svg @@ -0,0 +1,3045 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + Lumiera: Anatomy of the high-level-model + + + Ichthyostega + + + 8/2008 + + + + + + + + + + + + + + + + + + ∑ + + + + + + + + + + + + + + + + + Proc + + + + + + + + x + + + + + + + + + + + + + + Tap + + + + + + + + + + + + + + + + + + + + W + + + + + + + + + + + + + + + + + + + + + + Transition + + + + + + + + + + + + + + + + + + + + + + + Clip + + + + + + + + + + + + W + t + + + + + + + + + + + + + + + + + + + + + + + + Auto + + + + + + + + + + + + + + + + + + + + + + + Chan1 + + + + Chan2 + + + + + + + + + + + + + + + + + + + + + x + + + + + + + + + + + + + + + + + + + + + + + + + + + W + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + x + + + + + + + + + + + + + + + + + x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Meta + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + global Pipes + + + + EDL-1 + + + + EDL-2 + + + + + + + Anatomy of thehigh-level model + The model is an association of Media Objects, grouped to form Processing Pipes, which are a linear chain of data processing modules, starting from an source port and providing an exit point. Optionally, there may be a wiring plug, requesting the exit point to be connected to another pipe. When omitted, the wiring will be figured out automatically. Several pipes may be joined together by a transition, which in the general case simultaneously treats N media streams. Commonly, a transition simply combines two streams into one output. Individual Media Objects are attached, located or joined together by Placements. A Placement is a handle for a single MObject and contains a list of placement specifications, (called Locating Pin)Besides absolute and relative placement, there is also the possibility of a placement to stick directly to another MObject's placement, e.g. to attach an effect to a clip or to connect an automation data set to an effect. + + Actually a clip is handled as if it was comprised of local pipe(s). In the example shown here, a two-channel clip has three effects attached, plus a wiring plug. Each of those attachments is used only if applicable to the media stream type the respective pipe will process. Thus, effectively each channel (sub)clip gets its own specifically adapted processing pipe. + The Session contains several independent EDLs plus an output bus section (global Pipes). Each EDL holds a collection of MObjects placed within a Tree of Tracks. The wiring, if not defined locally within an MObject's placement, is derived by searching up this track tree and utilizing the wiring plug locating pins found there, if applicable. Besides routing to a global pipe, wiring plugs can also connect to the source port of an Meta-Clip. + diff --git a/doc/devel/uml/class132741.html b/doc/devel/uml/class132741.html index a9dd11ca8..89bb5e220 100644 --- a/doc/devel/uml/class132741.html +++ b/doc/devel/uml/class132741.html @@ -16,7 +16,7 @@ -

Declaration :

Directly inherited by : InvocationStateBase StateAdapter StateProxy

+

Declaration :

Directly inherited by : StateAdapter StateProxy

Artifact : stateproxy, Component(s) : Builder

Relation currFrame (<unidirectional association>)

Declaration :

diff --git a/doc/devel/uml/class142469.html b/doc/devel/uml/class142469.html index 31b631174..58c82f008 100644 --- a/doc/devel/uml/class142469.html +++ b/doc/devel/uml/class142469.html @@ -16,9 +16,8 @@ -

Declaration :

- -
Relation wiring (<unidirectional association>)

Declaration :

+

Declaration :

+

All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

diff --git a/doc/devel/uml/class142725.html b/doc/devel/uml/class142725.html index 13bdadf5b..93345b68f 100644 --- a/doc/devel/uml/class142725.html +++ b/doc/devel/uml/class142725.html @@ -17,5 +17,9 @@

Declaration :

Directly inherited by : NodeWiring

+
+ +
Operation callDown

Declaration :

  • Uml : + callDown(inout : State, in requiredOutput : uint) : , exceptions : BuffHandle
  • C++ : public: virtual callDown () throw (BuffHandle)
+

All public operations : callDown

diff --git a/doc/devel/uml/class143365.html b/doc/devel/uml/class143365.html index 8f96f6b27..c4e3718c3 100644 --- a/doc/devel/uml/class143365.html +++ b/doc/devel/uml/class143365.html @@ -16,7 +16,13 @@ -

Declaration :

-
+

Declaration :

+ +
Relation <association>

Declaration :

+
Relation <association>

Declaration :

+
Relation <association>

Declaration :

+
Relation <unidirectional association>

Declaration :

+
Operation callDown

Declaration :

  • Uml : + callDown() :
  • C++ : public: callDown ()
+

All public operations : callDown , callDown

diff --git a/doc/devel/uml/class143493.html b/doc/devel/uml/class143493.html index 63ef30fb2..37a6496d9 100644 --- a/doc/devel/uml/class143493.html +++ b/doc/devel/uml/class143493.html @@ -4,21 +4,18 @@ -Class InvocationStateBase +Class OperationBase -
Class InvocationStateBase
+
Class OperationBase

-

Declaration :

Directly inherited by : Caching

-
-
-

All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

+

Declaration :

Directly inherited by : FeedCache ProcessData ReadSource

diff --git a/doc/devel/uml/class143621.html b/doc/devel/uml/class143621.html index 39379446c..649d441e7 100644 --- a/doc/devel/uml/class143621.html +++ b/doc/devel/uml/class143621.html @@ -4,21 +4,20 @@ -Class Caching +Class QueryCache -
Class Caching
+
Class QueryCache

-

Declaration :

Directly inherited by : Process

+

Declaration :

Directly inherited by : Strategy

-

All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

diff --git a/doc/devel/uml/class143749.html b/doc/devel/uml/class143749.html index 2d3726110..426d12aaa 100644 --- a/doc/devel/uml/class143749.html +++ b/doc/devel/uml/class143749.html @@ -4,21 +4,21 @@ -Class Process +Class PullInput -
Class Process
+
Class PullInput

-

Declaration :

Directly inherited by : InPlace

+

Declaration :

Directly inherited by : QueryCache Strategy

-
-

All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

+ +
Relation <association>

Declaration :

diff --git a/doc/devel/uml/class143877.html b/doc/devel/uml/class143877.html index b3164a70a..bad34df65 100644 --- a/doc/devel/uml/class143877.html +++ b/doc/devel/uml/class143877.html @@ -4,21 +4,20 @@ -Class InPlace +Class ReadSource -
Class InPlace
+
Class ReadSource

-

Declaration :

Directly inherited by : StateProxy

+

Declaration :

Directly inherited by : Strategy

-

All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

diff --git a/doc/devel/uml/class144005.html b/doc/devel/uml/class144005.html index 9fd2629bc..bc2bf60f2 100644 --- a/doc/devel/uml/class144005.html +++ b/doc/devel/uml/class144005.html @@ -4,19 +4,19 @@ -Class WiringTable +Class BuffTable -
Class WiringTable
+
Class BuffTable

-

Declaration :

+

Declaration :

Relation <directional aggregation by value>

Declaration :

Relation <unidirectional association>

Declaration :

diff --git a/doc/devel/uml/class144261.html b/doc/devel/uml/class144261.html new file mode 100644 index 000000000..d9c258fab --- /dev/null +++ b/doc/devel/uml/class144261.html @@ -0,0 +1,25 @@ + + + + + + +Class Invocation + + + + + +
Class Invocation
+

+ + + + +

Declaration :

+ +
Relation <unidirectional association>

Declaration :

+
Relation <unidirectional association>

Declaration :

+
Relation <unidirectional association>

Declaration :

+ + diff --git a/doc/devel/uml/class144389.html b/doc/devel/uml/class144389.html new file mode 100644 index 000000000..fb3f25daf --- /dev/null +++ b/doc/devel/uml/class144389.html @@ -0,0 +1,24 @@ + + + + + + +Class ProcessData + + + + + +
Class ProcessData
+

+ + + + +

Declaration :

Directly inherited by : PullInput

+
+ +
Relation <association>

Declaration :

+ + diff --git a/doc/devel/uml/class144517.html b/doc/devel/uml/class144517.html new file mode 100644 index 000000000..8eace63da --- /dev/null +++ b/doc/devel/uml/class144517.html @@ -0,0 +1,25 @@ + + + + + + +Class Strategy + + + + + +
Class Strategy
+

+ + + + +

Declaration :

+ +
Relation <association>

Declaration :

+
Relation <association>

Declaration :

+
Relation <association>

Declaration :

+ + diff --git a/doc/devel/uml/class144645.html b/doc/devel/uml/class144645.html new file mode 100644 index 000000000..c5cc7c0cb --- /dev/null +++ b/doc/devel/uml/class144645.html @@ -0,0 +1,23 @@ + + + + + + +Class FeedCache + + + + + +
Class FeedCache
+

+ + + + +

Declaration :

Directly inherited by : ProcessData

+
+
+ + diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 7992c89cf..319577971 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -27,11 +27,11 @@ AutoAutomation data for some parameter (i.e. a time varying function) BackendCache BuffHandle +BuffTable Buildableinterface BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuilderToolinterfaceUsed according to the visitor pattern: each Tool contains the concrete implementation for one task to be done to the various MObject classes BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. -Caching Caller Categorytree like classification of Assets Clipbookkeeping (asset) view of a media clip. @@ -60,6 +60,7 @@ ExplicitPlacementinterface External Factorya template for generating functor-like Factory objects, used to encapsulate object creation and providing access via smart-pointers only. +FeedCache File FileHandle FileHandleCache @@ -74,10 +75,9 @@ FrameDescriptorinterfaceA FrameDescriptor implements the higher level interfaces for frames. Further refinements are made by subclassing and policy classes FrameReference GLBuf -InPlace InterpolatorProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalid -InvocationStateBase +Invocation Label Link LocatingPinAn element with value semantics, which actually implements the placement of some MObject by positioning it in some way. @@ -94,6 +94,7 @@ MutexI provided a reworked Mutex class in my Cinelerra2 repository NodeCreatorToolThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render. NodeWiring +OperationBase ParameterDescriptor and access object for a plugin parameter. Parameters may be provided with values from the session, and this values may be automated. ParamProviderinterfaceA facility to get the actual value of a plugin/effect parameter PathManagerWhile building a render engine, this Strategy class decides on the actual render strategy in accordance to the current controller settings (system state) @@ -105,13 +106,16 @@ Previewalternative version of the media data, probably with lower resolution Prockey abstraction: data processing asset ProcDispatcher -Process +ProcessData Processor ProcNodeinterfaceKey abstraction of the Render Engine: A Data processing Node ProcPattspecial type of structural Asset representing information how to build some part of the render engine's processing nodes network. ProjectorSpecial video processing node used to scale and translate image data. +PullInput +QueryCache QueryHandlerinterface QueryHandlerImpl +ReadSource RelativeLocation RelTypeenumthe possible kinds of RelativePlacements RenderEngine @@ -132,6 +136,7 @@ StateAdapter StateProxyimplementation std::exceptionauxiliary +Strategy Structkey abstraction: structural asset ThreadWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads Timedenotes a temporal position (time point), based on timeline start.

investigate posix.4 realtime timers, wrap these here @@ -147,7 +152,6 @@ VFrame Visitable WiringDescriptor -WiringTable Wish WriteBuffer WriteBufferPool diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index f89fb300a..8e8c2d9a6 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -28,11 +28,11 @@ Auto
BackendCache
BuffHandle
+BuffTable
Buildable
BuilderFacade
BuilderTool
BuildInstruct
-Caching
Caller
Category
Clip
@@ -61,6 +61,7 @@ ExplicitPlacement
External
Factory
+FeedCache
File
FileHandle
FileHandleCache
@@ -75,10 +76,9 @@ FrameDescriptor
FrameReference
GLBuf
-InPlace
Interpolator
Invalid
-InvocationStateBase
+Invocation
Label
Link
LocatingPin
@@ -95,6 +95,7 @@ Mutex
NodeCreatorTool
NodeWiring
+OperationBase
Parameter
ParamProvider
PathManager
@@ -106,13 +107,16 @@ Preview
Proc
ProcDispatcher
-Process
+ProcessData
Processor
ProcNode
ProcPatt
Projector
+PullInput
+QueryCache
QueryHandler
QueryHandlerImpl
+ReadSource
RelativeLocation
RelType
RenderEngine
@@ -133,6 +137,7 @@ StateAdapter
StateProxy
std::exception
+Strategy
Struct
Thread
Time
@@ -148,7 +153,6 @@ VFrame
Visitable
WiringDescriptor
-WiringTable
Wish
WriteBuffer
WriteBufferPool
diff --git a/doc/devel/uml/fig128005.png b/doc/devel/uml/fig128005.png index e9bef7624..4cae19a1d 100644 Binary files a/doc/devel/uml/fig128005.png and b/doc/devel/uml/fig128005.png differ diff --git a/doc/devel/uml/fig128901.png b/doc/devel/uml/fig128901.png index 6bb94e8cc..bd2b52fe1 100644 Binary files a/doc/devel/uml/fig128901.png and b/doc/devel/uml/fig128901.png differ diff --git a/doc/devel/uml/fig129029.png b/doc/devel/uml/fig129029.png index 6313cb7fb..3e8223916 100644 Binary files a/doc/devel/uml/fig129029.png and b/doc/devel/uml/fig129029.png differ diff --git a/doc/devel/uml/fig129285.png b/doc/devel/uml/fig129285.png index d8f8bec2e..c42d770d3 100644 Binary files a/doc/devel/uml/fig129285.png and b/doc/devel/uml/fig129285.png differ diff --git a/doc/devel/uml/fig130053.png b/doc/devel/uml/fig130053.png index 9cee6c87a..c25a4871d 100644 Binary files a/doc/devel/uml/fig130053.png and b/doc/devel/uml/fig130053.png differ diff --git a/doc/devel/uml/fig130821.png b/doc/devel/uml/fig130821.png index 8f9dab369..0c951bf06 100644 Binary files a/doc/devel/uml/fig130821.png and b/doc/devel/uml/fig130821.png differ diff --git a/doc/devel/uml/fig131973.png b/doc/devel/uml/fig131973.png index 78f068e2d..d16d88131 100644 Binary files a/doc/devel/uml/fig131973.png and b/doc/devel/uml/fig131973.png differ diff --git a/doc/devel/uml/fig132357.png b/doc/devel/uml/fig132357.png index e454c31e9..8f89db240 100644 Binary files a/doc/devel/uml/fig132357.png and b/doc/devel/uml/fig132357.png differ diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index de5e95e2f..1081df7d3 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -116,7 +116,7 @@ Documentation
Artifact Lumiera

Depends on common

Depends on gui

Depends on proc

Depends on backend

the main executable to be built

-

executable associated with : mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation

+

executable associated with : glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label

Artifact main

Artifact source

@@ -902,12 +902,16 @@ reuse exiting Engine

Selection :

Transformation
-
-
Class Caching
-
Class Process
-
Class InPlace
-
+
+
+
Class PullInput
+
+
+
Class FeedCache
+
Class Strategy
+
Class BuffTable
+

diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index 8712d7074..a873c25b0 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -17,8 +17,8 @@ - + @@ -28,10 +28,10 @@ - - + + diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index ab57596c5..33d5ebd2f 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -55,12 +55,12 @@ - + - - + + diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index db64b33db..3a6ba7379 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -24,6 +24,7 @@ + @@ -36,8 +37,8 @@ - + diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 1612ca9ea..8432e5cc6 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -19,7 +19,8 @@ - + + @@ -29,34 +30,34 @@ - - - - - - - + + + + + - - - + + + + + + + - - - - - - - - - - + + + + + + + + diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 1f6fd3f19..a7245b34b 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,14 +18,14 @@
NameKindDescription
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
<flow>transition
Assetsclass view
ATTACHattributeattach subject to anchor (e.g. an effect to a clip)
au1class instance
aud_aclass instance
aud_Aclass instance
aud_aclass instance
audioclass instance
audio1class instance
audio1class instance
audio1class instance
audio1class instance
audio1class instance
autoartifactMedia Object holding automation data
AutoclassAutomation data for some parameter (i.e. a time varying function)
Automation Entitiesclass diagram
BackendCacheclass
BackendLayerpackage
BuffHandleclass
BuffTableclass
buildoperation
build flowactivity diagram
build necessary?decision activity node
buildableartifactmarker interface denoting any MObject able to be treated by Tools
buildEngineoperationMain Operation of the Builder: create a render engine for a given part of the timeline
Buildercomponent
builderpackagesourcecode package

The Builder creating the Render Engine,
located within the MObject Subsystem
Builderpackage
builderpackagesourcecode package

The Builder creating the Render Engine,
located within the MObject Subsystem
Builder Entitiesclass diagram
Builder Workingsclass view
BuilderFacadeclassProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade
NameKindDescription
Cachecomponent
Cachecomponent view
Cachingclass
callDownoperation
callDownoperation
Callerclass
categoryrelationprimary tree like classification of the asset
Categoryclasstree like classification of Assets
chainrelationChain of additional Placements further constraining the position of this MObject
checked_inrelationchecked_in objects are subject of cache aging and must be not in use
checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
class instanceclass instance
clearoperationclear current session contents
without resetting overall session config.
Afterwards, the session will contain only one
empty EDL, while all Assets are retained.
client codecomponent
Clipclassbookkeeping (asset) view of a media clip.
- + - + diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 5e1189dd5..56bc1daaf 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -18,6 +18,7 @@
NameKindDescription
edlartifactthe (high level) Edit Decision List within the current Session
EDLclass
EDLcomponent
EDLclass
EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
edlsrelation
EffectclassEffect or media processing component
effectartifactEffect or media processing component
effectartifactEDL representation of a pluggable and automatable effect.
effectartifactEffect or media processing component
Effectclass
elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
+ diff --git a/doc/devel/uml/index_72.html b/doc/devel/uml/index_72.html index 3547e6f3e..7e5b73a00 100644 --- a/doc/devel/uml/index_72.html +++ b/doc/devel/uml/index_72.html @@ -23,8 +23,8 @@ - +
NameKindDescription
Factoryclassa template for generating functor-like Factory objects, used to encapsulate object creation and providing access via smart-pointers only.
FeedCacheclass
fetchoperation
Fileclass
filerelation
Hierarchyclass diagramLumiera Exception hierarchy
howtoProcoperation@return descriptor how to build a render pipeline corresponding to this media
hubartifactspecial ProcNode used to build data distributing connections
HUEclass instance
HUEclass instance
HUEclass instance
diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 9a0a77429..e127cf07e 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,10 +20,9 @@ idattributeAsset primary key. In Memory Databaseclass diagram inFixtureactivity action pin -InPlaceclass -inputclass instance -inputclass instance inputclass instance +inputclass instance +inputclass instance instanceoperation instructionsrelation Interfaceclass view @@ -32,7 +31,7 @@ interpolatorartifactdenotes a facility to get (continuously interpolated) parameter values InterpolatorclassProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalidclass -InvocationStateBaseclass +Invocationclass iporelation isActiveoperationweather this asset is swithced on and consequently included in the fixture and participates in rendering isCalculatedoperation diff --git a/doc/devel/uml/index_77.html b/doc/devel/uml/index_77.html index 1428ef6eb..e6d8e8031 100644 --- a/doc/devel/uml/index_77.html +++ b/doc/devel/uml/index_77.html @@ -33,8 +33,8 @@ MediaFactoryclassspecialized Asset Factory for configuring (new) media asset instances based on existing media files on disk; can create placeholder assets as well merge activity nodemerge activity node Metaclasskey abstraction: metadata and organisational asset -metaartifactabstract base class of all MObjects representing meta data or processing instructions metaartifactkey abstraction: metadata and organisational asset +metaartifactabstract base class of all MObjects representing meta data or processing instructions Metaclass mobjectartifactKey Abstraction: A Media Object in the Session mobjectpackagesourcecode package

MObject Subsystem
including the Session (EDL), Builder and Processing Controller diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index d1fdc83c0..e17eadde8 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -18,6 +18,7 @@ + diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index a3268b59b..368babe6a 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -53,8 +53,8 @@ - + @@ -67,6 +67,7 @@ +
NameKindDescription
offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation?
OperationBaseclass
orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi".
ouputclass instance
ouputclass instance
Proc-Asset Relationsclass diagram
proc-componentscomponent diagram
ProcDispatcherclass
Processclass
processoperation
ProcessDataclass
ProcessingLayerpackage
Processorclass
processorartifacta single render pipeline for one segment of the timeline
projectorartifactvideo ProcNode for scaling and translating image data
providerrelation
pulloperation
PullInputclass
diff --git a/doc/devel/uml/index_81.html b/doc/devel/uml/index_81.html index 5a521bd2f..6367201fd 100644 --- a/doc/devel/uml/index_81.html +++ b/doc/devel/uml/index_81.html @@ -20,6 +20,7 @@ queryclass view Query System overviewcomponent view query useuse case view +QueryCacheclass QueryHandlerclass QueryHandlerImplclass diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index b5b305e10..9b107d854 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -17,14 +17,15 @@ + - + diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index 5dd747140..4ea8bf79b 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -32,8 +32,8 @@ - + @@ -47,8 +47,8 @@ - + @@ -64,6 +64,7 @@ + diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index b0541e88b..96532f18f 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -42,13 +42,13 @@ - + - +
NameKindDescription
ReadSourceclass
refPointclass instance
regoperationregisters an asset object in the internal DB, providing its unique key
registryrelation@internal Table or DB holding all registered asset instances.
relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one
RelativeLocationclass
releaseBufferoperation
relTypeattributethe kind of relation denoted by this Placement
RelTypeclassthe possible kinds of RelativePlacements
relTypeattributethe kind of relation denoted by this Placement
removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB
Render Entitiesclass diagram
Render Mechanicsclass diagram
Service Componentsclass view
Sessioncomponent
sessionartifactInterface: the session edited by the user
sessionpackagesourcecode package

Everything concerning the EDL and Session, within the MObject Subsystem
Sessionclass view
sessionpackagesourcecode package

Everything concerning the EDL and Session, within the MObject Subsystem
SessionclassPrimary Interface for all editing tasks.
The session contains defaults, all the assets being edited, and a set of EDL with the individual MObjects to be manipulated and rendered.
Session structureclass diagram
sessionimplartifactholds the complete session data to be edited by the user
SimpleClipclassElementary clip consisting of only one media stream
SmartPointerclass
SmartPointersclass view
sourcerelationmedia source of this clip
sourcerelationthe media source this clip referes to
sourcerelationmedia source of this clip
SourceclassSource Node: represents a media source to pull data from.
sourceartifactRepresentation of a Media source
Source Overviewdeployment diagram
StateProxyclass
stateproxyartifactKey Interface representing a render process and encapsulating state
std::exceptionclass
Strategyclass
Structclasskey abstraction: structural asset
structartifactkey abstraction: structural asset
Struct-Asset Relationsclass diagram
trafoartifacttransforming processing Node
treatoperation
treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated.
treatoperation
treatoperation
treatoperation
treatoperation
treatoperation
treatoperation
treatoperation
treatoperation
treatoperation
TypeHandlerclass
TypeHandler<Pipe>class
diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index cda6a585e..3538c8202 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -22,18 +22,18 @@ vframeartifacta buffer and render process holding a Video frame vid1class instance vid_Aclass instance -vid_aclass instance +vid_aclass instance vid_Aclass instance vid_Aclass instance -vid_aclass instance -videoclass instance -videoclass instance +vid_aclass instance videoclass instance +videoclass instance videoclass instance +videoclass instance video1class instance -video1class instance video1class instance video1class instance +video1class instance video1class instance video1class instance Visitableclass diff --git a/doc/devel/uml/index_87.html b/doc/devel/uml/index_87.html index 7e2b7e31f..616839a54 100644 --- a/doc/devel/uml/index_87.html +++ b/doc/devel/uml/index_87.html @@ -20,9 +20,7 @@ whatoperation whatoperationthe base class of all exceptions thrown by the standard library when to queryuse case diagram -wiringrelation WiringDescriptorclass -WiringTableclass wiringTemplaterelation wishartifactLocatingPin representing a low-priority directive by the user,
to be fulfilled only if possible (and after satisfying the
more important LocatingPins) Wishclass diff --git a/doc/devel/uml/public_operations.html b/doc/devel/uml/public_operations.html index c252030f0..07fb079d7 100644 --- a/doc/devel/uml/public_operations.html +++ b/doc/devel/uml/public_operations.html @@ -23,6 +23,8 @@ buildAssembler buildEngineBuilderFacadeMain Operation of the Builder: create a render engine for a given part of the timeline buildProcessorPathManager +callDownNodeWiring +callDownWiringDescriptor chainPlacementcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. clearSessManagerclear current session contents
without resetting overall session config.
Afterwards, the session will contain only one
empty EDL, while all Assets are retained.
configureToolFactory @@ -67,12 +69,12 @@ saveSessManagercreate a complete, serialized representation
of the current session config and contents.
@todo how to serialize, prameters, return value? treatApplicable treatBuilderToolThis operation is to be overloaded for the specific MObject subclasses to be treated. -treatNodeCreatorTool treatNodeCreatorTool treatNodeCreatorTool +treatNodeCreatorTool treatNodeCreatorTool -treatSegmentationTool treatSegmentationTool +treatSegmentationTool treatSegmentationTool useFileFileProviderAnnounces that the application intends to use this file with mode (READ|WRITE|READWRITE) useTemporaryStorageFileProviderProvides a pool for interminate frames diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 965ac6079..29d794f7a 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -40,11 +40,11 @@ liblumicommon_a_SOURCES = \ noinst_HEADERS += \ $(liblumicommon_a_srcdir)/cmdline.hpp \ $(liblumicommon_a_srcdir)/factory.hpp \ + $(liblumicommon_a_srcdir)/frameid.hpp \ $(liblumicommon_a_srcdir)/singleton.hpp \ $(liblumicommon_a_srcdir)/singletonpolicies.hpp \ $(liblumicommon_a_srcdir)/singletonpreconfigure.hpp \ $(liblumicommon_a_srcdir)/lumitime.hpp \ - $(liblumicommon_a_srcdir)/typelist.hpp \ $(liblumicommon_a_srcdir)/visitor.hpp \ $(liblumicommon_a_srcdir)/visitordispatcher.hpp \ $(liblumicommon_a_srcdir)/visitorpolicies.hpp \ @@ -56,7 +56,10 @@ noinst_HEADERS += \ $(liblumicommon_a_srcdir)/query/mockconfigrules.hpp \ $(liblumicommon_a_srcdir)/singletonfactory.hpp \ $(liblumicommon_a_srcdir)/singletonsubclass.hpp \ - $(liblumicommon_a_srcdir)/typelistutil.hpp \ + $(liblumicommon_a_srcdir)/meta/typelist.hpp \ + $(liblumicommon_a_srcdir)/meta/configflags.hpp \ + $(liblumicommon_a_srcdir)/meta/generator.hpp \ + $(liblumicommon_a_srcdir)/meta/typelistutil.hpp \ $(liblumicommon_a_srcdir)/util.hpp \ $(liblumicommon_a_srcdir)/test/mockinjector.hpp \ $(liblumicommon_a_srcdir)/test/suite.hpp \ diff --git a/src/common/configrules.hpp b/src/common/configrules.hpp index 0968c88d4..e80ccfa8a 100644 --- a/src/common/configrules.hpp +++ b/src/common/configrules.hpp @@ -48,7 +48,7 @@ #include "common/p.hpp" #include "common/query.hpp" -#include "common/typelistutil.hpp" +#include "common/meta/generator.hpp" #include "common/singletonsubclass.hpp" //TODO: is it sensible to bring in the types explicitly here? (it's not necessary, but may be convenient...) diff --git a/src/proc/frame.hpp b/src/common/frameid.hpp similarity index 50% rename from src/proc/frame.hpp rename to src/common/frameid.hpp index 239987e97..9cb95eb37 100644 --- a/src/proc/frame.hpp +++ b/src/common/frameid.hpp @@ -1,5 +1,5 @@ /* - FRAME.hpp - Key Abstraction: render process and buffer holding frame data. + FRAMEID.hpp - distinct identification of a single data frame Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,26 +21,36 @@ */ -#ifndef PROC_INTERFACE_FRAME_H -#define PROC_INTERFACE_FRAME_H +#ifndef LUMIERA_FRAMEID_H +#define LUMIERA_FRAMEID_H -namespace proc_interface +namespace lumiera { /** - * TODO: how to relate to Cehteh's Frame entity in the Backend? - * The latter is the fundamental Frame entity, wheras this Object - * rather represents a buffer set containing frame date. + * Identification tuple for addressing frames unambiguosly. + * + * @todo currently (7/08) this is a dummy implementation to find out + * what interface the Proc layer needs. Probably the backend will + * later on define what is actually needed; this header should then + * be replaced by a combined C/C++ header */ - class Frame + class FrameID : boost::totally_ordered { - ///////////////// + long dummy; + public: + FrameID(long dum=0) : dummy(dum) {} + operator long () { return dummy; } + + bool operator< (const FrameID& of) const { return dummy < of.dummy; } + bool operator== (const FrameID& of) const { return dummy == of.dummy; } }; - - -} // namespace proc_interface + + + +} // namespace lumiera #endif diff --git a/src/common/meta/configflags.hpp b/src/common/meta/configflags.hpp new file mode 100644 index 000000000..c63552855 --- /dev/null +++ b/src/common/meta/configflags.hpp @@ -0,0 +1,191 @@ +/* + CONFIGFLAGS.hpp - Building classes based on configuration cases + + 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. + +*/ + + +/** @file configflags.hpp + ** Under some circumstances it is necessary to assemble functionality + ** out of elementary building blocks. Especially, this assembly can be + ** expressed as template specialisations directed by a configuration type. + ** Thus, the purpose of this header is to encode flag-like configuraitons + ** as distinct types, which can be used to select such specialisations. + ** Each possible configuration can be encoded as a list of flags, which allows + ** to generate, filter and process those configurations. The final goal is to + ** automatically generate a factory which is able to deliver objects + ** configured according to the situation encoded in the flags. + ** + ** @note currently there is an inherent limitation to configurations defined by + ** a maximum of 5 independant flags. While it is easy to increase this limit, + ** you should consider that the final goal is to genarate template instantiations, + ** which would lead to more and more code bloat with growing number of possible + ** combination. + ** + ** @see proc::engine::config::Strategy usage example + ** @see proc::engine::config::ConfigSelector + ** @see typelist.hpp + ** + */ + + +#ifndef LUMIERA_META_CONFIGFLAGS_H +#define LUMIERA_META_CONFIGFLAGS_H + + +#include "common/meta/typelist.hpp" + + +namespace lumiera { + namespace typelist { + + const size_t CONFIG_FLAGS_MAX = 5; + + + template struct Flag { typedef Flag ID; }; + template<> struct Flag<0> { typedef NullType ID; }; + + + template< char f1=0 + , char f2=0 + , char f3=0 + , char f4=0 + , char f5=0 + > + struct Flags + { + typedef typename Types< typename Flag::ID + , typename Flag::ID + , typename Flag::ID + , typename Flag::ID + , typename Flag::ID + >::List + Tuple; + typedef Tuple List; + }; + + + template< char f1=0 + , char f2=0 + , char f3=0 + , char f4=0 + , char f5=0 + > + struct Config ///< distinct type representing a configuration + { + typedef typename Flags::Tuple Flags; + typedef Flags List; + }; + + + + template + struct ConfigSetFlag; ///< set (prepend) the Flag to the given config + + template< char Fl + , char f1 + , char f2 + , char f3 + , char f4 + , char IGN + > + struct ConfigSetFlag > + { + typedef typelist::Config Config; + }; + + + + /** build a configuration type from a list-of-flags */ + template > + struct BuildConfigFromFlags + { + typedef CONF Config; + typedef Config Type; + }; + template + struct BuildConfigFromFlags< Node,FLAGS>, CONF> + { + typedef typename ConfigSetFlag< Fl + , typename BuildConfigFromFlags::Config + >::Config Config; + typedef Config Type; + }; + /** create a configuration type for the given list-of-flags */ + template + struct DefineConfigByFlags : BuildConfigFromFlags { }; + + + /** + * Helper for calculating values and for + * invoking runtime code based on a given FlagTuple. + * Can also be used on a Typelist of several Configs. + * The latter case is typically used to invoke an operation + * while ennumerating all Flag-Configurations defined in Code. + * An example would be to build (at runtime) an dispatcher table. + * Explanation: For the Case covering a List of Configs, we provide + * a templated visitaion function, which can accept a functor object + * to be invoked on each Configuration. + */ + template + struct FlagInfo; + + template + struct FlagInfo, FLAGS> > + { + enum{ BITS = MAX(ff, FlagInfo::BITS) + , CODE = (1<::CODE + }; + }; + template<> + struct FlagInfo + { + enum{ BITS = 0 + , CODE = 0 + }; + + template + static typename FUNC::Ret + accept (FUNC& functor) + { + return functor.done(); + } + }; + template + struct FlagInfo > + { + typedef typename CONF::Flags ThisFlags; + enum{ BITS = MAX (char(FlagInfo::BITS), char(FlagInfo::BITS)) + }; + + template + static typename FUNC::Ret + accept (FUNC& functor) + { + functor.template visit(FlagInfo::CODE); + return FlagInfo::accept (functor); + } + }; + + + + } // namespace typelist + +} // namespace lumiera +#endif diff --git a/src/common/typelistutil.hpp b/src/common/meta/generator.hpp similarity index 86% rename from src/common/typelistutil.hpp rename to src/common/meta/generator.hpp index 3fb6a531e..59f340b5d 100644 --- a/src/common/typelistutil.hpp +++ b/src/common/meta/generator.hpp @@ -1,5 +1,5 @@ /* - TYPELISTUTIL.hpp - metaprogramming utilities for lists-of-types + GENERATOR.hpp - metaprogramming utilities for generating classes and interfaces Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -38,7 +38,7 @@ This code is heavily inspired by */ -/** @file typelistutil.hpp +/** @file generator.hpp ** Helpers for working with lumiera::typelist::Types (i.e. lists-of-types). ** The main purpose is to build interfaces and polymorphic implementations ** (using virtual functions) based on templated Types or Collections of types, @@ -50,10 +50,10 @@ This code is heavily inspired by */ -#ifndef LUMIERA_TYPELISTUTIL_H -#define LUMIERA_TYPELISTUTIL_H +#ifndef LUMIERA_META_GENERATOR_H +#define LUMIERA_META_GENERATOR_H -#include "common/typelist.hpp" +#include "common/meta/typelist.hpp" @@ -196,42 +196,6 @@ namespace lumiera }; - /** - * Metafunction counting the number of Types in the collection - */ - template - struct count; - template<> - struct count - { - enum{ value = 0 }; - }; - template - struct count > - { - enum{ value = 1 + count::value }; - }; - - /** - * Metafunction " max( sizeof(T) ) for T in TYPES " - */ - template - struct maxSize; - template<> - struct maxSize - { - enum{ value = 0 }; - }; - template - struct maxSize > - { - enum{ thisval = sizeof(TY) - , nextval = maxSize::value - , value = nextval > thisval? nextval:thisval - }; - }; - - } // namespace typelist } // namespace lumiera diff --git a/src/common/typelist.hpp b/src/common/meta/typelist.hpp similarity index 94% rename from src/common/typelist.hpp rename to src/common/meta/typelist.hpp index f358a605e..c2d4568d0 100644 --- a/src/common/typelist.hpp +++ b/src/common/meta/typelist.hpp @@ -53,8 +53,8 @@ This code is heavily inspired by */ -#ifndef LUMIERA_TYPELIST_H -#define LUMIERA_TYPELIST_H +#ifndef LUMIERA_META_TYPELIST_H +#define LUMIERA_META_TYPELIST_H @@ -64,11 +64,15 @@ namespace lumiera namespace typelist { - class NullType { }; + class NullType + { + typedef NullType List; + }; template struct Node { + typedef Node List; typedef H Head; typedef T Tail; }; @@ -113,6 +117,8 @@ namespace lumiera }; + typedef Node NodeNull; + } // namespace typelist diff --git a/src/common/meta/typelistutil.hpp b/src/common/meta/typelistutil.hpp new file mode 100644 index 000000000..3a0d56284 --- /dev/null +++ b/src/common/meta/typelistutil.hpp @@ -0,0 +1,213 @@ +/* + TYPELISTUTIL.hpp - Utils for working with lists-of-types + + 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. + +*/ + + +#ifndef LUMIERA_META_TYPELISTUTIL_H +#define LUMIERA_META_TYPELISTUTIL_H + + + +#include "common/meta/typelist.hpp" + +namespace lumiera { + namespace typelist { + + + /** + * Metafunction counting the number of Types in the collection + */ + template + struct count; + template<> + struct count + { + enum{ value = 0 }; + }; + template + struct count > + { + enum{ value = 1 + count::value }; + }; + + /** + * Metafunction " max( sizeof(T) ) for T in TYPES " + */ + template + struct maxSize; + template<> + struct maxSize + { + enum{ value = 0 }; + }; + template + struct maxSize > + { + enum{ thisval = sizeof(TY) + , nextval = maxSize::value + , value = nextval > thisval? nextval:thisval + }; + }; + + + /** apply a transformation (template) to each type in the list */ + template class _TRANS_> + struct Apply { typedef TY List; }; + + template< class TY, class TYPES + , template class _TRANS_ + > + struct Apply, _TRANS_ > { typedef Node< typename _TRANS_::Type + , typename Apply::List + > List; }; + + + template + struct CondNode { typedef TAIL Next; }; + + template + struct CondNode { typedef Node Next; }; + + /** filter away those types which don't fulfill a predicate metafunction */ + template< class TYPES + , template class _P_ ///< a template providing a boolean member \c ::value + > + struct Filter; + + template class _P_> + struct Filter { typedef NullType List; }; + + template< class TY, class TYPES + , template class _P_ + > + struct Filter,_P_> { typedef typename CondNode< _P_::value + , TY + , typename Filter::List + >::Next + List; }; + + + /** append lists-of-types */ + template + struct Append { typedef Node::List> List; }; + + template< class TY, class TYPES + , class TAIL + > + struct Append, TAIL> { typedef Node::List> List; }; + + template + struct Append > { typedef Node List; }; + + template + struct Append, NullType> { typedef Node List; }; + + template + struct Append { typedef Node List; }; + + template + struct Append { typedef Node List; }; + + template<> + struct Append { typedef NullType List; }; + + + + /** + * prefix each of the elements, + * yielding a list-of lists-of-types + */ + template + struct PrefixAll { typedef Node< typename Append::List, NullType> List; }; + + template + struct PrefixAll { typedef NullType List; }; + + template + struct PrefixAll { typedef Node< typename Append::List, NullType> List; }; + + template< class T + , class TY, class TYPES + > + struct PrefixAll > { typedef Node< typename Append::List + , typename PrefixAll::List + > List; }; + + + + + template + struct Distribute { typedef typename PrefixAll::List List; }; + + template + struct Distribute { typedef NullType List; }; + + template< class TY, class TYPES + , class TAIL + > + struct Distribute,TAIL> { typedef typename Append< typename PrefixAll::List + , typename Distribute::List + >::List + List; }; + + + + /** use a permutation generator + * for creating a list of all possible combinations + */ + template< class X + , template class _PERMU_> + struct Combine { typedef typename Distribute< typename _PERMU_::List + , Node + >::List List; }; + template< template class _PERMU_> + struct Combine { typedef Node List; }; + + template< class TY, class TYPES + , template class _PERMU_> + struct Combine,_PERMU_> { typedef typename Distribute< typename _PERMU_::List + , typename Combine::List + >::List List; }; + + /** permutation generator for the Combine metafunction, + * yielding an "on" and "off" case + */ + template + struct FlagOnOff + { + typedef Node > List; + }; + + + /** generate all possible on-off combinations of the given flags */ + template + struct CombineFlags + { + typedef typename Combine::List List; + }; + + + + + } // namespace typelist + +} // namespace lumiera +#endif diff --git a/src/common/meta/util.hpp b/src/common/meta/util.hpp new file mode 100644 index 000000000..b01a412fa --- /dev/null +++ b/src/common/meta/util.hpp @@ -0,0 +1,76 @@ +/* + UTIL.hpp - metaprogramming helpers and utilities + + 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. + +*/ + + +#ifndef LUMIERA_META_UTIL_H +#define LUMIERA_META_UTIL_H + + + +namespace lumiera { + + + /* types for figuring out the overload resolution chosen by the compiler */ + + typedef char Yes_t; + struct No_t { char padding[8]; }; + + + + namespace typelist { + + /** semi-automatic detection if an instantiation is possible. + * Requires help by the template to be tested, which needs to define + * a typedef member \c is_defined. The embedded metafunction Test can be used + * as a predicate for filtering types which may yield a valid instantiation + * of the candidate template in question. + * \par + * A fully automated solution for this problem is impossible by theoretic reasons. + * Any non trivial use of such a \c is_defined trait would break the "One Definition Rule", + * as the state of any type can change from "partially defined" to "fully defined" over + * the course of any translation unit. Thus, even if there may be a \em solution out there, + * we can expect it to break at some point by improvements/fixes to the C++ Language. + */ + template class _CandidateTemplate_> + struct Instantiation + { + + template + class Test + { + typedef _CandidateTemplate_ Instance; + + template + static Yes_t check(typename U::is_defined *); + template + static No_t check(...); + + public: + static const bool value = (sizeof(Yes_t)==sizeof(check(0))); + }; + }; + + + } // namespace typelist + +} // namespace lumiera +#endif diff --git a/src/common/singletonfactory.hpp b/src/common/singletonfactory.hpp index e62385d2c..0065227df 100644 --- a/src/common/singletonfactory.hpp +++ b/src/common/singletonfactory.hpp @@ -35,7 +35,7 @@ This code is heavily inspired by #define LUMIERA_SINGLETONFACTORY_H -#include "common/singletonpolicies.hpp" //< several Policies usable together with SingletonFactory +#include "common/singletonpolicies.hpp" ///< several Policies usable together with SingletonFactory #include "common/util.hpp" #include "proc/nobugcfg.hpp" diff --git a/src/common/util.hpp b/src/common/util.hpp index 7f8704554..c71ba3b6a 100644 --- a/src/common/util.hpp +++ b/src/common/util.hpp @@ -237,4 +237,8 @@ namespace util * and we probably will enforce this design rule in future. */ #define INSTANCEOF(CLASS, EXPR) (dynamic_cast (EXPR)) +/** the inevitalbe MAX macro, sometimes still necessary in template code */ +#define MAX(A,B) (A < B) ? (B) : (A) + + #endif /*UTIL_HPP_*/ diff --git a/src/common/variant.hpp b/src/common/variant.hpp index 561b7149c..751c2d9fc 100644 --- a/src/common/variant.hpp +++ b/src/common/variant.hpp @@ -41,7 +41,8 @@ #define LUMIERA_VARIANT_H -#include "common/typelistutil.hpp" +#include "common/meta/typelistutil.hpp" +#include "common/meta/generator.hpp" #include diff --git a/src/common/visitor.hpp b/src/common/visitor.hpp index 3d22f11e6..49bbcedb5 100644 --- a/src/common/visitor.hpp +++ b/src/common/visitor.hpp @@ -79,7 +79,7 @@ Credits for many further implementation ideas go to #include "common/visitorpolicies.hpp" #include "common/visitordispatcher.hpp" -#include "common/typelist.hpp" +#include "common/meta/typelist.hpp" namespace lumiera diff --git a/src/common/wrapperptr.hpp b/src/common/wrapperptr.hpp index e17963eff..81afa1177 100644 --- a/src/common/wrapperptr.hpp +++ b/src/common/wrapperptr.hpp @@ -29,7 +29,7 @@ #include "common/variant.hpp" #include "common/accesscasted.hpp" -#include "common/typelist.hpp" +#include "common/meta/typelist.hpp" #include "proc/mobject/placement.hpp" #include "common/p.hpp" diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 340579ed5..65e9ae6b7 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -63,8 +63,9 @@ TimelinePanel::TimelinePanel() : toolbar.append(seperator2); toolbar.append(zoomIn, mem_fun(this, &TimelinePanel::on_zoom_in)); toolbar.append(zoomOut, mem_fun(this, &TimelinePanel::on_zoom_out)); - - toolbar.set_icon_size(IconSize(ICON_SIZE_LARGE_TOOLBAR)); + +// doesn't compile on Etch +// toolbar.set_icon_size(IconSize(ICON_SIZE_LARGE_TOOLBAR)); toolbar.set_toolbar_style(TOOLBAR_ICONS); // Add the toolbar diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index a4d8b825f..85b32ba80 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -49,5 +49,5 @@ noinst_HEADERS += \ $(liblumi_a_srcdir)/mrucache.h \ $(liblumi_a_srcdir)/time.h \ $(liblumi_a_srcdir)/appconfig.hpp \ - $(liblumi_a_srcdir)/appconfig.hpp + $(liblumi_a_srcdir)/lifecycleregistry.hpp diff --git a/src/proc/Makefile.am b/src/proc/Makefile.am index aa758771f..10de0d119 100644 --- a/src/proc/Makefile.am +++ b/src/proc/Makefile.am @@ -25,9 +25,8 @@ liblumiproc_a_CXXFLAGS = $(CXXFLAGS) -Wall liblumiproc_a_CPPFLAGS = -I$(top_srcdir)/src/ liblumiproc_a_SOURCES = \ - $(liblumiproc_a_srcdir)/controllerfacade.cpp \ - $(liblumiproc_a_srcdir)/frame.cpp \ - $(liblumiproc_a_srcdir)/stateproxy.cpp \ + $(liblumiproc_a_srcdir)/controllerfacade.cpp \ + $(liblumiproc_a_srcdir)/state.cpp \ $(liblumiproc_a_srcdir)/asset.cpp \ $(liblumiproc_a_srcdir)/assetmanager.cpp \ $(liblumiproc_a_srcdir)/nobugcfg.cpp @@ -66,25 +65,19 @@ liblumiprocengine_a_CXXFLAGS = $(CXXFLAGS) -Wall liblumiprocengine_a_CPPFLAGS = -I$(top_srcdir)/src/ liblumiprocengine_a_SOURCES = \ - $(liblumiprocengine_a_srcdir)/aframe.cpp \ - $(liblumiprocengine_a_srcdir)/arender.cpp \ - $(liblumiprocengine_a_srcdir)/codecadapter.cpp \ - $(liblumiprocengine_a_srcdir)/exitnode.cpp \ - $(liblumiprocengine_a_srcdir)/glbuf.cpp \ - $(liblumiprocengine_a_srcdir)/glpipe.cpp \ - $(liblumiprocengine_a_srcdir)/glrender.cpp \ - $(liblumiprocengine_a_srcdir)/hub.cpp \ + $(liblumiprocengine_a_srcdir)/buffhandle.cpp \ $(liblumiprocengine_a_srcdir)/link.cpp \ $(liblumiprocengine_a_srcdir)/mask.cpp \ + $(liblumiprocengine_a_srcdir)/nodefactory.cpp \ + $(liblumiprocengine_a_srcdir)/nodewiring.cpp \ $(liblumiprocengine_a_srcdir)/pluginadapter.cpp \ $(liblumiprocengine_a_srcdir)/processor.cpp \ $(liblumiprocengine_a_srcdir)/procnode.cpp \ $(liblumiprocengine_a_srcdir)/projector.cpp \ $(liblumiprocengine_a_srcdir)/renderengine.cpp \ - $(liblumiprocengine_a_srcdir)/source.cpp \ - $(liblumiprocengine_a_srcdir)/trafo.cpp \ - $(liblumiprocengine_a_srcdir)/vframe.cpp \ - $(liblumiprocengine_a_srcdir)/vrender.cpp + $(liblumiprocengine_a_srcdir)/source.cpp \ + $(liblumiprocengine_a_srcdir)/stateproxy.cpp \ + $(liblumiprocengine_a_srcdir)/trafo.cpp @@ -113,8 +106,9 @@ liblumiprocmobjectbuilder_a_CPPFLAGS = -I$(top_srcdir)/src/ liblumiprocmobjectbuilder_a_SOURCES = \ $(liblumiprocmobjectbuilder_a_srcdir)/assembler.cpp \ $(liblumiprocmobjectbuilder_a_srcdir)/conmanager.cpp \ - $(liblumiprocmobjectbuilder_a_srcdir)/nodecreatertool.cpp \ - $(liblumiprocmobjectbuilder_a_srcdir)/segmentationtool.cpp + $(liblumiprocmobjectbuilder_a_srcdir)/nodecreatortool.cpp \ + $(liblumiprocmobjectbuilder_a_srcdir)/segmentationtool.cpp \ + $(liblumiprocmobjectbuilder_a_srcdir)/toolfactory.cpp liblumiprocmobjectcontroller_a_srcdir = $(top_srcdir)/src/proc/mobject/controller @@ -124,8 +118,7 @@ liblumiprocmobjectcontroller_a_CXXFLAGS = $(CXXFLAGS) -Wall liblumiprocmobjectcontroller_a_CPPFLAGS = -I$(top_srcdir)/src/ liblumiprocmobjectcontroller_a_SOURCES = \ - $(liblumiprocmobjectcontroller_a_srcdir)/pathmanager.cpp \ - $(liblumiprocmobjectcontroller_a_srcdir)/renderstate.cpp + $(liblumiprocmobjectcontroller_a_srcdir)/pathmanager.cpp liblumiprocmobjectsession_a_srcdir = $(top_srcdir)/src/proc/mobject/session @@ -138,9 +131,12 @@ liblumiprocmobjectsession_a_SOURCES = \ $(liblumiprocmobjectsession_a_srcdir)/abstractmo.cpp \ $(liblumiprocmobjectsession_a_srcdir)/allocation.cpp \ $(liblumiprocmobjectsession_a_srcdir)/auto.cpp \ - $(liblumiprocmobjectsession_a_srcdir)/compoundclip.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/clip.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/compoundclip.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/constraint.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/defsmanager.cpp \ $(liblumiprocmobjectsession_a_srcdir)/effect.cpp \ - $(liblumiprocmobjectsession_a_srcdir)/fixedlocation.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/fixedlocation.cpp \ $(liblumiprocmobjectsession_a_srcdir)/label.cpp \ $(liblumiprocmobjectsession_a_srcdir)/meta.cpp \ $(liblumiprocmobjectsession_a_srcdir)/relativelocation.cpp \ @@ -152,9 +148,6 @@ liblumiprocmobjectsession_a_SOURCES = \ $(liblumiprocmobjectsession_a_srcdir)/edl.cpp \ $(liblumiprocmobjectsession_a_srcdir)/session.cpp \ $(liblumiprocmobjectsession_a_srcdir)/track.cpp \ - $(liblumiprocmobjectsession_a_srcdir)/clip.cpp \ - $(liblumiprocmobjectsession_a_srcdir)/constraint.cpp \ - $(liblumiprocmobjectsession_a_srcdir)/defsmanager.cpp \ $(liblumiprocmobjectsession_a_srcdir)/fixture.cpp \ $(liblumiprocmobjectsession_a_srcdir)/locatingpin.cpp \ $(liblumiprocmobjectsession_a_srcdir)/mobjectfactory.cpp \ @@ -183,15 +176,6 @@ noinst_HEADERS += \ $(liblumiproc_a_srcdir)/asset/track.hpp \ $(liblumiproc_a_srcdir)/asset/unknown.hpp \ $(liblumiproc_a_srcdir)/controllerfacade.hpp \ - $(liblumiproc_a_srcdir)/engine/aframe.hpp \ - $(liblumiproc_a_srcdir)/engine/arender.hpp \ - $(liblumiproc_a_srcdir)/engine/codecadapter.hpp \ - $(liblumiproc_a_srcdir)/engine/exitnode.hpp \ - $(liblumiproc_a_srcdir)/engine/glbuf.hpp \ - $(liblumiproc_a_srcdir)/engine/glpipe.hpp \ - $(liblumiproc_a_srcdir)/engine/glrender.hpp \ - $(liblumiproc_a_srcdir)/engine/hub.hpp \ - $(liblumiproc_a_srcdir)/engine/link.hpp \ $(liblumiproc_a_srcdir)/engine/mask.hpp \ $(liblumiproc_a_srcdir)/engine/pluginadapter.hpp \ $(liblumiproc_a_srcdir)/engine/procnode.hpp \ @@ -199,15 +183,12 @@ noinst_HEADERS += \ $(liblumiproc_a_srcdir)/engine/renderengine.hpp \ $(liblumiproc_a_srcdir)/engine/source.hpp \ $(liblumiproc_a_srcdir)/engine/trafo.hpp \ - $(liblumiproc_a_srcdir)/engine/vframe.hpp \ - $(liblumiproc_a_srcdir)/engine/vrender.hpp \ $(liblumiproc_a_srcdir)/engine/processor.hpp \ - $(liblumiproc_a_srcdir)/frame.hpp \ $(liblumiproc_a_srcdir)/mobject/builder/assembler.hpp \ $(liblumiproc_a_srcdir)/mobject/builder/buildertool.hpp \ $(liblumiproc_a_srcdir)/mobject/builder/conmanager.hpp \ - $(liblumiproc_a_srcdir)/mobject/builder/nodecreatertool.hpp \ $(liblumiproc_a_srcdir)/mobject/builder/segmentationtool.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/toolfactory.hpp \ $(liblumiproc_a_srcdir)/mobject/builderfacade.hpp \ $(liblumiproc_a_srcdir)/mobject/controller/pathmanager.hpp \ $(liblumiproc_a_srcdir)/mobject/controller/renderstate.hpp \ @@ -241,7 +222,6 @@ noinst_HEADERS += \ $(liblumiproc_a_srcdir)/mobject/mobject.hpp \ $(liblumiproc_a_srcdir)/mobject/placement.hpp \ $(liblumiproc_a_srcdir)/mobject/session.hpp \ - $(liblumiproc_a_srcdir)/stateproxy.hpp \ $(liblumiproc_a_srcdir)/asset.hpp \ $(liblumiproc_a_srcdir)/assetmanager.hpp \ $(liblumiproc_a_srcdir)/lumiera.hpp \ diff --git a/src/proc/asset/buildinstruct.hpp b/src/proc/asset/buildinstruct.hpp index 8b1162103..dee85d58d 100644 --- a/src/proc/asset/buildinstruct.hpp +++ b/src/proc/asset/buildinstruct.hpp @@ -108,7 +108,15 @@ namespace asset : public InstructEntry { template - BuildInstruct (T& instr) : InstructEntry(instr) {} + BuildInstruct (T& instr) : InstructEntry() {} + + // TODO: this ctor is *not* correct, just to make it compile + // There is a strange problem with boost::variant, probably becausse the + // template parameter T could be anything (but actually we know it's one + // of our Instruction types. + // I have to reinvestigate this design anyway, and probably will replace + // the boost::variant by something else, derive from a common base or such. + // Note: as of 8/2008 ProcPatt is just a draft and not implemented. }; diff --git a/src/proc/asset/procpatt.cpp b/src/proc/asset/procpatt.cpp index d5173b9ea..5f2c842fd 100644 --- a/src/proc/asset/procpatt.cpp +++ b/src/proc/asset/procpatt.cpp @@ -91,7 +91,8 @@ namespace asset else { DoAttach entry(node, where); - instructions_.push_back(BuildInstruct(entry)); + BuildInstruct instruction(entry); + instructions_.push_back(instruction); } TODO ("declare dependency??"); return *this; diff --git a/src/proc/engine/aframe.cpp b/src/proc/engine/aframe.cpp deleted file mode 100644 index e8713897b..000000000 --- a/src/proc/engine/aframe.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - AFrame - buffer holding a Audio samples for the render process - - 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 "proc/engine/aframe.hpp" - -namespace engine - { - - /** */ - - - - -} // namespace engine diff --git a/src/proc/engine/aframe.hpp b/src/proc/engine/aframe.hpp deleted file mode 100644 index 0d77e15ca..000000000 --- a/src/proc/engine/aframe.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - AFRAME.hpp - buffer holding a Audio samples for the render process - - 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. - -*/ - - -#ifndef ENGINE_AFRAME_H -#define ENGINE_AFRAME_H - -#include "proc/frame.hpp" - - - -namespace engine - { - - - class AFrame : public proc_interface::Frame - {}; - - - -} // namespace engine -#endif diff --git a/src/proc/engine/arender.hpp b/src/proc/engine/arender.hpp deleted file mode 100644 index 79c70c460..000000000 --- a/src/proc/engine/arender.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - ARENDER.hpp - Representation of a Audio Render process - - 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. - -*/ - - -#ifndef ENGINE_ARENDER_H -#define ENGINE_ARENDER_H - -#include "proc/stateproxy.hpp" - - - -namespace engine - { - - - /** - * Representation of a Audio render process - */ - class ARender : public proc_interface::StateProxy - {}; - - - -} // namespace engine -#endif diff --git a/src/proc/engine/arender.cpp b/src/proc/engine/buffhandle.cpp similarity index 87% rename from src/proc/engine/arender.cpp rename to src/proc/engine/buffhandle.cpp index ac7171998..30ae603e2 100644 --- a/src/proc/engine/arender.cpp +++ b/src/proc/engine/buffhandle.cpp @@ -1,5 +1,5 @@ /* - ARender - Representation of a Audio Render process + BuffHandle - Buffer handling support for the render engine Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,14 +21,12 @@ * *****************************************************/ -#include "proc/engine/arender.hpp" +#include "proc/engine/buffhandle.hpp" -namespace engine - { - - /** */ +namespace engine { + /** */ } // namespace engine diff --git a/src/proc/engine/buffhandle.hpp b/src/proc/engine/buffhandle.hpp new file mode 100644 index 000000000..51ce1c135 --- /dev/null +++ b/src/proc/engine/buffhandle.hpp @@ -0,0 +1,104 @@ +/* + BUFFHANDLE.hpp - Buffer handling support for the render engine + + 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. + +*/ + +/** @file buffhandle.hpp + ** Various bits needed to support the buffer management within the render nodes. + ** When pulling data from predecessor nodes and calculating new data, each render node + ** needs several input and output buffers. These may be allocated and provided by several + ** different "buffer providers" (for example the frame cache). For accessing those buffers, + ** the node needs to keep a table of buffer pointers, and for releasing the buffers later + ** on, we need some handles. The usage pattern of those buffer pointer tables is stack-like, + ** thus it makes sense to utilize a single large buffer pointer array per pull() calldown + ** sequence and dynamically claim small chunks for each node. + ** + ** @see nodeoperation.hpp + ** @see bufftable.hpp storage for the buffer table + ** @see engine::Invocation + */ + +#ifndef ENGINE_BUFFHANDLE_H +#define ENGINE_BUFFHANDLE_H + + +#include "common/error.hpp" + + +namespace engine { + + + + /** + * Handle for a buffer for processing data, abstracting away the actual implementation. + * The real buffer pointer can be retrieved by dereferencing this smart-handle class. + */ + struct BuffHandle + { + typedef float Buff; + typedef Buff* PBuff;//////TODO define the Buffer type(s) + + PBuff + operator->() const + { + return pBuffer_; + } + Buff& + operator* () const + { + ENSURE (pBuffer_); + return *pBuffer_; + } + + protected: + PBuff pBuffer_; + long sourceID_; + }; + + + /** + * Buffer Type information. + * Given a BufferDescriptor, it is possible to allocate a buffer + * of suitable size and type by using State::allocateBuffer(). + */ + struct BufferDescriptor + { + char typeID_; ///////TODO define the Buffer type(s) + }; + + + class ProcNode; + typedef ProcNode* PNode; + + + struct ChannelDescriptor ///////TODO collapse this with BufferDescriptor? + { + BufferDescriptor bufferType; + }; + + struct InChanDescriptor : ChannelDescriptor + { + PNode dataSrc; ///< the ProcNode to pull this input from + uint srcChannel; ///< output channel to use on the predecessor node + }; + + +} // namespace engine +#endif diff --git a/src/proc/engine/bufftable.hpp b/src/proc/engine/bufftable.hpp new file mode 100644 index 000000000..ac1329265 --- /dev/null +++ b/src/proc/engine/bufftable.hpp @@ -0,0 +1,162 @@ +/* + BUFFTABLE.hpp - Table of buffer pointers to be used by the render nodes + + 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. + +*/ + + +#ifndef ENGINE_BUFFHTABLE_H +#define ENGINE_BUFFHTABLE_H + + +#include "common/error.hpp" +#include "proc/engine/buffhandle.hpp" +#include "proc/engine/procnode.hpp" + +#include +#include +#include + + + +namespace engine { + + using std::pair; + using std::vector; + + + /** + * Tables of buffer handles and corresponding dereferenced buffer pointers. + * Used within the invocation of a processing node to calculate data. + * The tables are further differentiated into input data buffers and output + * data buffers. The tables are supposed to be implemented as bare "C" arrays, + * thus the array of real buffer pointers can be fed directly to the + * processing function of the respective node. + */ + struct BuffTable + { + typedef BuffHandle * PHa; + typedef BuffHandle::PBuff * PBu; + typedef pair Chunk; + + PHa outHandle; + PHa inHandle; + PBu outBuff; + PBu inBuff; + }; + + + class BuffTableStorage + { + vector hTab_; + vector pTab_; + size_t level_; + + public: + BuffTableStorage (const size_t maxSiz) + : hTab_(maxSiz), + pTab_(maxSiz), + level_(0) + { } + + ~BuffTableStorage() { ASSERT (0==level_, "buffer management logic broken."); } + + protected: + + friend class BuffTableChunk; + + /** allocate the given number of slots + * starting at current level to be used + * by the newly created BuffTableChunk + */ + BuffTable::Chunk + claim (uint slots) + { + ASSERT (pTab_.size() == hTab_.size()); + REQUIRE (level_+slots <= hTab_.size()); + + size_t prev_level (level_); + level_ += slots; + return std::make_pair (&hTab_[prev_level], + &pTab_[prev_level]); + } + + void + release (uint slots) + { + ASSERT (slots <= level_); + REQUIRE (level_ <= hTab_.size()); + REQUIRE (level_ <= pTab_.size()); + + level_ -= slots; + } + + bool + level_check (BuffTable::Chunk& prev_level) + { + return prev_level.first == &hTab_[level_] + && prev_level.second == &pTab_[level_]; + } + }; + + + /** + * to be allocated on the stack while evaluating a ProcNode#pull() call. + * The "current" State (StateProxy) maintains a BuffTableStorage (=pool), + * which can be used to crate such chunks. The claiming and releasing of + * slots in the BuffTableStorage is automatically tied to BuffTableChunk + * object's lifecycle. + */ + class BuffTableChunk + : public BuffTable, + boost::noncopyable + { + const uint siz_; + BuffTable::Chunk tab_; + BuffTableStorage& sto_; + + public: + BuffTableChunk (WiringDescriptor const& wd, BuffTableStorage& storage) + : siz_(wd.getNrI() + wd.getNrO()), + tab_(storage.claim (siz_)), + sto_(storage) + { + const uint nrO(wd.getNrO()); + + // Setup the public visible table locations + this->outHandle = &tab_.first[ 0 ]; + this->inHandle = &tab_.first[nrO]; + this->outBuff = &tab_.second[ 0 ]; + this->inBuff = &tab_.second[nrO]; + } + + ~BuffTableChunk () + { + sto_.release (siz_); + ASSERT ( sto_.level_check (tab_), + "buffer management logic broken."); + } + }; + + + + + +} // namespace engine +#endif diff --git a/src/proc/engine/codecadapter.cpp b/src/proc/engine/codecadapter.cpp deleted file mode 100644 index b65694679..000000000 --- a/src/proc/engine/codecadapter.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - CodecAdapter - Processing Node for (de)coding media data - - 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 "proc/engine/codecadapter.hpp" - -namespace engine - { - - -} // namespace engine diff --git a/src/proc/engine/codecadapter.hpp b/src/proc/engine/codecadapter.hpp deleted file mode 100644 index 724763eaa..000000000 --- a/src/proc/engine/codecadapter.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - CODECADAPTER.hpp - Processing Node for (de)coding media data - - 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. - -*/ - - -#ifndef ENGINE_CODECADAPTER_H -#define ENGINE_CODECADAPTER_H - -#include "proc/engine/trafo.hpp" - - - -namespace engine - { - - - /** - * Adapter for wiring an externally loaded - * codec into the render pipeline. The decoding - * process thus is integrated into the framework - * of the Renderengine, while the actual implementation - * can be delegated to an external library accessed - * through Lumiera's data backend. - */ - class CodecAdapter : public Trafo - {}; - - - -} // namespace engine -#endif diff --git a/src/proc/engine/glbuf.cpp b/src/proc/engine/glbuf.cpp deleted file mode 100644 index 6970a3114..000000000 --- a/src/proc/engine/glbuf.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - GLBuf - a buffer and render process holding a Video frame for OpenGL rendering - - 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 "proc/engine/glbuf.hpp" - -namespace engine - { - - /** */ - - - - -} // namespace engine diff --git a/src/proc/engine/glbuf.hpp b/src/proc/engine/glbuf.hpp deleted file mode 100644 index 8e8ee2ea5..000000000 --- a/src/proc/engine/glbuf.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - GLBUF.hpp - a buffer and render process holding a Video frame for OpenGL rendering - - 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. - -*/ - - -#ifndef ENGINE_GLBUF_H -#define ENGINE_GLBUF_H - -#include "proc/frame.hpp" - - - -namespace engine - { - - - class GLBuf : public proc_interface::Frame - {}; - -} // namespace engine -#endif diff --git a/src/proc/engine/glpipe.cpp b/src/proc/engine/glpipe.cpp deleted file mode 100644 index 9d4d28b48..000000000 --- a/src/proc/engine/glpipe.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - GLPipe - specialized connection element for handling OpenGL implementation details - - 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 "proc/engine/glpipe.hpp" - -namespace engine - { - - /** */ - - - - -} // namespace engine diff --git a/src/proc/engine/glpipe.hpp b/src/proc/engine/glpipe.hpp deleted file mode 100644 index 39a98a7ab..000000000 --- a/src/proc/engine/glpipe.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - GLPIPE.hpp - specialized connection element for handling OpenGL implementation details - - 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. - -*/ - - -#ifndef ENGINE_GLPIPE_H -#define ENGINE_GLPIPE_H - -#include "proc/engine/link.hpp" - - - -namespace engine - { - - - /** - * specialized connection node used to handle the transfer of OpenGL data - * from a image bitmap into texture form. - */ - class GLPipe : public Link - {}; - - - - -} // namespace engine -#endif diff --git a/src/proc/engine/glrender.cpp b/src/proc/engine/glrender.cpp deleted file mode 100644 index 32420201b..000000000 --- a/src/proc/engine/glrender.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - GLRender - Representation of a OpenGL accellerated Video render process - - 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 "proc/engine/glrender.hpp" - -namespace engine - { - - /** */ - - - -} // namespace engine diff --git a/src/proc/engine/glrender.hpp b/src/proc/engine/glrender.hpp deleted file mode 100644 index e9c73c3a3..000000000 --- a/src/proc/engine/glrender.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - GLRENDER.hpp - Representation of a OpenGL accellerated Video render process - - 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. - -*/ - - -#ifndef ENGINE_GLRENDER_H -#define ENGINE_GLRENDER_H - -#include "proc/stateproxy.hpp" - - - -namespace engine - { - - - /** - * Representation of a OpenGL accelerated Video render process - */ - class GLRender : public proc_interface::StateProxy - {}; - -} // namespace engine -#endif diff --git a/src/proc/engine/hub.cpp b/src/proc/engine/hub.cpp deleted file mode 100644 index 394d24197..000000000 --- a/src/proc/engine/hub.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - Hub - special ProcNode used to build data distributing connections - - 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 "proc/engine/hub.hpp" - -namespace engine - { - - /** */ - - - - -} // namespace engine diff --git a/src/proc/engine/hub.hpp b/src/proc/engine/hub.hpp deleted file mode 100644 index b6ec69fcb..000000000 --- a/src/proc/engine/hub.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - HUB.hpp - special ProcNode used to build data distributing connections - - 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. - -*/ - - -#ifndef ENGINE_HUB_H -#define ENGINE_HUB_H - -#include "proc/engine/procnode.hpp" - - - -namespace engine - { - - - class Hub : public ProcNode - {}; - ///TODO: seems rather we don't need this one anymore?? - //////// to be decided after the implementing the basic render engine.... - - - - -} // namespace engine -#endif diff --git a/src/proc/engine/link.hpp b/src/proc/engine/link.hpp index ad2f3a625..d677fca9c 100644 --- a/src/proc/engine/link.hpp +++ b/src/proc/engine/link.hpp @@ -40,6 +40,10 @@ namespace engine */ class Link : public ProcNode { + Link (WiringDescriptor const& wd) + : ProcNode(wd) + { } + ///////TODO: flatten hierarchy if we don't have common functionallity for all Link-Subclasses ///////TODO: can be decdiede when we know more how to handle OpenGL rendering }; diff --git a/src/proc/engine/exitnode.cpp b/src/proc/engine/nodefactory.cpp similarity index 67% rename from src/proc/engine/exitnode.cpp rename to src/proc/engine/nodefactory.cpp index 8c26b7cd9..d439232f3 100644 --- a/src/proc/engine/exitnode.cpp +++ b/src/proc/engine/nodefactory.cpp @@ -1,5 +1,5 @@ /* - ExitNode - special Processing Node providing "pullable" output + NodeFactory - Interface for creating processing nodes of variouos kinds Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,13 +21,21 @@ * *****************************************************/ -#include "proc/engine/exitnode.hpp" +#include "proc/engine/nodefactory.hpp" +#include "proc/mobject/session/effect.hpp" -namespace engine +namespace engine { + + using mobject::Placement; + using mobject::session::Effect; + + + /** create a processing node able to render an effect */ + PTrafo + NodeFactory::operator() (Placement const&) { - - /** */ - + UNIMPLEMENTED ("create proc node for Effect/Plugin"); + } } // namespace engine diff --git a/src/proc/engine/exitnode.hpp b/src/proc/engine/nodefactory.hpp similarity index 53% rename from src/proc/engine/exitnode.hpp rename to src/proc/engine/nodefactory.hpp index 1cb6e51c2..7abae3340 100644 --- a/src/proc/engine/exitnode.hpp +++ b/src/proc/engine/nodefactory.hpp @@ -1,5 +1,5 @@ /* - EXITNODE.hpp - special Processing Node providing "pullable" output + NODEFACTORY.hpp - Interface for creating processing nodes of variouos kinds Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,25 +21,46 @@ */ -#ifndef ENGINE_EXITNODE_H -#define ENGINE_EXITNODE_H +#ifndef ENGINE_NODEFACTORY_H +#define ENGINE_NODEFACTORY_H #include "proc/engine/procnode.hpp" +#include "proc/mobject/placement.hpp" -namespace engine - { +namespace mobject { + namespace session { + + class Clip; + class Effect; + typedef Placement PEffect; + // TODO: class Transition; + + } // namespace mobject::session + +} // namespace mobject + + +namespace engine { + + using std::vector; + + class Trafo; + typedef Trafo* PTrafo; ///< @note ProcNode is handled by pointer and bulk allocated/dealocated /** - * The output end of each render pipeline. - * Pulling from such exit nodes actually ivokes the render process + * Create processing nodes based on given objects of the high-level model. */ - class ExitNode : public ProcNode - {}; - - + class NodeFactory + { + + public: + + PTrafo operator() (mobject::session::PEffect const&); + + }; } // namespace engine #endif diff --git a/src/proc/engine/nodeinvocation.hpp b/src/proc/engine/nodeinvocation.hpp new file mode 100644 index 000000000..8b350d382 --- /dev/null +++ b/src/proc/engine/nodeinvocation.hpp @@ -0,0 +1,216 @@ +/* + NODEINVOCATION.hpp - Organize the invocation state within a single pull() call + + 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. + +*/ + +/** @file nodeinvocation.hpp + ** Organize the state related to the invocation of s single ProcNode::pull() call + ** This header defines part of the "glue" which holds together the render node network + ** and enables to pull result frames from the nodes. Doing so requires some invocation + ** local state to be maintained, especially a table of buffers used to carry out the + ** calculations. Further, getting the input buffers filled requires to issue recursive + ** \c pull() calls, which on the whole creates a stack-like assembly of local invocation + ** state. + ** The actual steps to be carried out for a \c pull() call are dependant on the configuration + ** of the node to pull. Each node has been preconfigured by the builder with a WiringDescriptor + ** and a concrete type of a StateAdapter. The actual sequence of steps is defined in the header + ** nodeoperation.hpp out of a set of basic operation steps. These steps all use the passed in + ** Invocation object (a sub-interface of StateAdapter) to access the various aspects of the + ** invocation state. + ** + ** \par composition of the Invocation State + ** For each individual ProcNode#pull() call, the WiringAdapter#callDown() builds an StateAdapter + ** instance directly on the stack, managing the actual buffer pointers and state references. Using this + ** StateAdapter, the predecessor nodes are pulled. The way these operations are carried out is encoded + ** in the actual StateAdapter type known to the NodeWiring (WiringAdapter) instance. All of these actual + ** StateAdapter types are built as implementing the engine::State interface. + ** + ** @see engine::ProcNode + ** @see engine::StateProxy + ** @see engine::BuffTable + ** @see nodewiring.hpp interface for building/wiring the nodes + ** + */ + +#ifndef ENGINE_NODEINVOCATION_H +#define ENGINE_NODEINVOCATION_H + + +#include "proc/state.hpp" +#include "proc/engine/procnode.hpp" +#include "proc/engine/buffhandle.hpp" +#include "proc/engine/bufftable.hpp" + + + + +namespace engine { + + + /** + * Adapter to shield the ProcNode from the actual buffer management, + * allowing the processing function within ProcNode to use logical + * buffer IDs. StateAdapter is created on the stack for each pull() + * call, using setup/wiring data preconfigured by the builder. + * Its job is to provide the actual implementation of the Cache + * push / fetch and recursive downcall to render the source frames. + */ + class StateAdapter + : public State + { + protected: + State& parent_; + State& current_; + + StateAdapter (State& callingProcess) + : parent_ (callingProcess), + current_(callingProcess.getCurrentImplementation()) + { } + + virtual State& getCurrentImplementation () { return current_; } + + + + public: /* === proxying the State interface === */ + + virtual void releaseBuffer (BuffHandle& bh) { current_.releaseBuffer (bh); } + + virtual void is_calculated (BuffHandle const& bh) { current_.is_calculated (bh); } + + virtual BuffHandle fetch (FrameID const& fID) { return current_.fetch (fID); } + + // note: allocateBuffer() is choosen specifically based on the actual node wiring + + }; + + + + + + /** + * Invocation context state. + * A ref to this type is carried through the chain of NEXT::step() functions + * which form the actual invocation sequence. The various operations in this sequence + * access the context via the references in this struct, while also using the inherited + * public State interface. The object instance actually used as Invocation is created + * on the stack and parametrized according to the necessities of the invocation sequence + * actually configured. Initially, this real instance is configured without BuffTable, + * because the invocation may be short-circuited due to Cache hit. Otherwise, when + * the invocation sequence actually prepares to call the process function of this + * ProcNode, a buffer table chunk is allocated by the StateProxy and wired in. + */ + struct Invocation + : StateAdapter + { + WiringDescriptor const& wiring; + const uint outNr; + + BuffTable* buffTab; + + protected: + /** creates a new invocation context state, without BuffTable */ + Invocation (State& callingProcess, WiringDescriptor const& w, uint o) + : StateAdapter(callingProcess), + wiring(w), outNr(o), + buffTab(0) + { } + + const uint nrO() const { return wiring.getNrO(); } + const uint nrI() const { return wiring.getNrI(); } + const uint buffTabSize() const { return nrO()+nrI(); } + + /** setup the link to an externally allocated buffer table */ + void setBuffTab (BuffTable* b) { this->buffTab = b; } + + bool + buffTab_isConsistent () + { + return (buffTab) + && (0 < buffTabSize()) + && (nrO()+nrI() <= buffTabSize()) + && (buffTab->inBuff == &buffTab->outBuff[nrO()] ) + && (buffTab->inHandle == &buffTab->outHandle[nrO()]) + ; + } + + + }; + + + struct AllocBufferFromParent ///< using the parent StateAdapter for buffer allocations + : Invocation + { + AllocBufferFromParent (State& sta, WiringDescriptor const& w, const uint outCh) + : Invocation(sta, w, outCh) {} + + virtual BuffHandle + allocateBuffer (BufferDescriptor const& bd) { return parent_.allocateBuffer(bd); } + }; + + struct AllocBufferFromCache ///< using the global current State, which will delegate to Cache + : Invocation + { + AllocBufferFromCache (State& sta, WiringDescriptor const& w, const uint outCh) + : Invocation(sta, w, outCh) {} + + virtual BuffHandle + allocateBuffer (BufferDescriptor const& bd) { return current_.allocateBuffer(bd); } + }; + + + /** + * The real invocation context state implementation. It is created + * by the NodeWiring (WiringDescriptor) of the processing node which + * is pulled by this invocation, hereby using the internal configuration + * information to guide the selecton of the real call sequence + * + * \par assembling the call sequence implementation + * Each ProcNode#pull() call creates such a StateAdapter subclass on the stack, + * with a concrete type according to the WiringDescriptor of the node to pull. + * This concrete type encodes a calculation Strategy, which is assembled + * as a chain of policy templates on top of OperationBase. For each of the + * possible configuratons we define such a chain (see bottom of nodeoperation.hpp). + * The WiringFactory defined in nodewiring.cpp actually drives the instantiation + * of all those possible combinations. + */ + template + class ActualInvocationProcess + : public BufferProvider + { + public: + ActualInvocationProcess (State& callingProcess, WiringDescriptor const& w, const uint outCh) + : BufferProvider(callingProcess, w, outCh) + { } + + /** contains the details of Cache query and recursive calls + * to the predecessor node(s), eventually followed by the + * ProcNode::process() callback + */ + BuffHandle retrieve () + { + return Strategy::step (*this); + } + }; + + + + +} // namespace engine +#endif diff --git a/src/proc/engine/nodeoperation.hpp b/src/proc/engine/nodeoperation.hpp new file mode 100644 index 000000000..b30c6cbeb --- /dev/null +++ b/src/proc/engine/nodeoperation.hpp @@ -0,0 +1,311 @@ +/* + NODEOPERATION.hpp - Specify how the nodes call each other and how processing is organized + + 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. + +*/ + +/** @file nodeoperation.hpp + ** Chunks of operation for invoking the rendernodes. + ** This header defines part of the "glue" which holds together the render node network + ** and enables to pull a result frames from the nodes. Especially, the aspect of + ** buffer management and cache query is covered here. Each node has been preconfigured by + ** the builder with a WiringDescriptor and a concrete type of a StateAdapter, including + ** a specific Configuration, because the node can be built to + ** - participate in the Caching or ignore the cache + ** - actually process a result or just pull frames from a source + ** - employ in-Place calculations or use separate in/out buffers + ** Additionally, each node may have a given number of input/output pins, expecting to + ** be provided with buffers holding a specific kind of data. + ** + ** \par composition of the invocation Strategy + ** For each individual ProcNode#pull() call, the WiringAdapter#callDown() builds an Invocation state + ** instance directly on the stack, holding references to the actual buffer pointers and state. Using this + ** StateAdapter, the predecessor nodes are pulled. The way these operations are carried out is encoded + ** in the actual type of Strategy, which is defined at the bottom of this header. Each Strategy is a chain + ** of elementary operations invoking each other (\c NEXT::step(invocation) ). Notably, all those possible + ** configurations are pre-build while compiling (it's a small number below 32 configuration instance). + ** To be able to select the Strategy for each configuration, we need a Factory (ConfigSelector defined in + ** nodewiringconfig). which is actually instantiated and used in nodewiring.cpp, which is the object + ** file holding all those instantiations. + ** + ** @see engine::ProcNode + ** @see engine::Invocation + ** @see engine::State + ** @see engine::NodeFactory + ** @see nodewiringconfig.hpp + ** @see nodewiring.hpp interface for building/wiring the nodes + ** + */ + +#ifndef ENGINE_NODEOPERATION_H +#define ENGINE_NODEOPERATION_H + + +#include "proc/state.hpp" +#include "proc/engine/procnode.hpp" +#include "proc/engine/buffhandle.hpp" +#include "proc/engine/bufftable.hpp" +#include "proc/engine/nodeinvocation.hpp" + +#include "common/meta/util.hpp" +#include "common/meta/configflags.hpp" + + + + +namespace engine { + namespace config { + + + /** + * Collection of functions used to build up the invocation sequence. + */ + class OperationBase + { + typedef lumiera::Yes_t is_defined; + }; + + template + struct QueryCache : NEXT + { + BuffHandle + step (Invocation& ivo) + { + BuffHandle fetched = ivo.fetch ( + this->genFrameID (ivo)); + if (fetched) + return fetched; + else + return NEXT::step (ivo); + } + }; + + + template + struct AllocBufferTable : NEXT + { + BuffHandle + step (Invocation& ivo) + { + BuffTableChunk buffTab (ivo.wiring, ivo.getBuffTableStorage()); + ivo.setBuffTab(&buffTab); + ASSERT (ivo.buffTab); + ASSERT (ivo.buffTab_isConsistent()); + + return NEXT::step (ivo); + } + }; + + + template + struct PullInput : NEXT + { + BuffHandle + step (Invocation& ivo) + { + BuffHandle * inH = ivo.buffTab->inHandle; + BuffHandle::PBuff *inBuff = ivo.buffTab->inBuff; + + for (uint i = 0; i < ivo.nrI(); ++i ) + { + inBuff[i] = + *(inH[i] = this->pullPredecessor(ivo,i)); // invoke predecessor + // now Input #i is ready... + } + return NEXT::step (ivo); // note: passing down a ref to the ProcessInvocation + } + }; + + + template + struct ReadSource : NEXT + { + BuffHandle + step (Invocation& ivo) + { + BuffHandle *inH = ivo.buffTab->inHandle; + BuffHandle *outH = ivo.buffTab->outHandle; + BuffHandle::PBuff *inBuff = ivo.buffTab->inBuff; + BuffHandle::PBuff *outBuff = ivo.buffTab->outBuff; + + ASSERT (ivo.nrO() == ivo.nrI() ); + + for (uint i = 0; i < ivo.nrI(); ++i ) + { + inBuff[i] = outBuff[i] = + *(inH[i] = outH[i] = this->getSource(ivo,i)); + // now Input #i is ready... + } + return NEXT::step (ivo); + } + }; + + + template + struct AllocOutput : NEXT + { + BuffHandle + step (Invocation& ivo) + { + ASSERT (ivo.buffTab); + ASSERT (ivo.nrO() < ivo.buffTabSize()); + BuffHandle *outH = ivo.buffTab->outHandle; + BuffHandle::PBuff *outBuff = ivo.buffTab->outBuff; + + for (uint i = 0; i < ivo.nrO(); ++i ) + { + outBuff[i] = + *(outH[i] = ivo.allocateBuffer (ivo.wiring.out[i].bufferType)); + // now Output buffer for channel #i is available... + } + return NEXT::step (ivo); + } + }; + + + template + struct ProcessData : NEXT + { + BuffHandle + step (Invocation& ivo) + { + ASSERT (ivo.buffTab); + ASSERT (ivo.buffTab_isConsistent()); + ASSERT (this->validateBuffers(ivo)); + + // Invoke our own process() function, + // providing the array of outBuffer+inBuffer ptrs + ivo.wiring.processFunction (ivo.buffTab->outBuff); + + return NEXT::step (ivo); + } + }; + + template + struct FeedCache : NEXT + { + BuffHandle + step (Invocation& ivo) + { + for (uint i = 0; i < ivo.nrO(); ++i ) + { + // declare all Outputs as finished + ivo.is_calculated(ivo.buffTab->outHandle[i]); + } + + return NEXT::step (ivo); + } + }; + + template + struct ReleaseBuffers : NEXT /////////////////TODO: couldn't this be done automatically by BuffTab's dtor?? + { ///////////////// this would require BuffHandle to be a smart ref.... + BuffHandle + step (Invocation& ivo) + { + // all buffers besides the required Output no longer needed + this->releaseBuffers(ivo.buffTab->outHandle, + ivo.buffTabSize(), + ivo.outNr); + + return ivo.buffTab->outHandle[ivo.outNr]; + } + }; + + + + + /* === declare the possible Assembly of these elementary steps === */ + + enum Cases + { + CACHING = 1, + PROCESS, + INPLACE, + + NOT_SET = 0, + NUM_Cases = INPLACE + }; + + + + template + struct SelectBuffProvider; + + template<> struct SelectBuffProvider { typedef AllocBufferFromCache Type; }; + template<> struct SelectBuffProvider { typedef AllocBufferFromParent Type; }; + template<> struct SelectBuffProvider { typedef AllocBufferFromCache Type; }; + template<> struct SelectBuffProvider<> { typedef AllocBufferFromParent Type; }; + + + template + struct Strategy ; + + using lumiera::typelist::Config; + + template + struct Strategy< Config > + : QueryCache< + AllocBufferTable< + PullInput< + AllocOutput< + ProcessData< + FeedCache< + ReleaseBuffers< + OperationBase > > > > > > > + { }; + + template + struct Strategy< Config > + : AllocBufferTable< + PullInput< + AllocOutput< + ProcessData< + ReleaseBuffers< + OperationBase > > > > > + { }; + + template<> + struct Strategy< Config<> > + : AllocBufferTable< + ReadSource< + ReleaseBuffers< + OperationBase > > > + { }; + + template<> + struct Strategy< Config > : Strategy< Config<> > { }; + + template<> + struct Strategy< Config > + : AllocBufferTable< + ReadSource< + AllocOutput< + ProcessData< // wiring_.processFunction is supposed to do just buffer copying here + ReleaseBuffers< + OperationBase > > > > > + { }; + + + + + } // namespace config + +} // namespace engine +#endif diff --git a/src/proc/engine/nodewiring.cpp b/src/proc/engine/nodewiring.cpp new file mode 100644 index 000000000..7d999aa48 --- /dev/null +++ b/src/proc/engine/nodewiring.cpp @@ -0,0 +1,138 @@ +/* + NodeWiring - Implementation of the node network and operation control + + 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 "proc/engine/procnode.hpp" +#include "proc/engine/nodewiring.hpp" +#include "proc/engine/nodeoperation.hpp" +#include "proc/engine/nodewiringconfig.hpp" + +#include "common/meta/typelistutil.hpp" + + +namespace engine { + + namespace config { + + using lumiera::typelist::Flags; + using lumiera::typelist::CombineFlags; + using lumiera::typelist::DefineConfigByFlags; + using lumiera::typelist::Instantiation; + using lumiera::typelist::Apply; + using lumiera::typelist::Filter; + + + typedef Flags::Tuple AllFlags; + + /** build the list of all possible flag combinations */ + typedef CombineFlags AllFlagCombinations; + + /** build a configuration type for each of those flag combinations */ + typedef Apply AllConfigs; + + /** filter those configurations which actually define a wiring strategy */ + typedef Filter::Test> PossibleConfigs; + + } // namespace config + + + + + namespace { // internal: setting up a factory for each required configuration + + using config::ConfigSelector; + + class Alloc {}; ///////////////TODO + + + template + class WiringDescriptorFactory + { + Alloc& alloc_; + + public: + WiringDescriptorFactory(Alloc& a) + : alloc_(a) {} + + WiringDescriptor& + operator() () + { + /////////////////////////////////////////////TODO + + typedef config::Strategy Strategy; + typedef typename config::SelectBuffProvider<>::Type BuffProvider; ////////////////////////TODO: how to extract the required flags from CONF?? + typedef ActualInvocationProcess InvocationStateType; + + typedef NodeWiring Product; + + Product * dummy (0); + return *dummy; + } + }; + + typedef WiringDescriptor& (FunctionType)(void); + + typedef ConfigSelector< WiringDescriptorFactory ///< Factory template + , FunctionType ///< function signature of the Factory + , Alloc& ///< allocator fed to all factories + > WiringSelector; + + + struct WiringFactoryImpl + { + WiringSelector selector; + + WiringFactoryImpl (Alloc& alloc) + : selector(config::PossibleConfigs::List(), alloc) + { } + }; + + } // (END) internals + + + /////////////////////////////TODO: define the ctor + + + /** create and configure a concrete wiring descriptor to tie + * a ProcNode to its predecessor nodes. This includes selecting + * the actual StateProxy type, configuring it out of some operation + * control templates (policy classes). Compiling this operator function + * actually drives the necessary template instantiations for all cases + * encountered while building the node network. + * The created WiringDescriptor object is bulk allocated similar to the ProcNode + * objects for a given segment of the Timeline. It should be further configured + * with the actual predecessor nodes pointers and can then be used to create + * the new processing node to be wired up. + */ + WiringDescriptor& + WiringFactory::operator() (uint nrOut, uint nrIn, bool cache) + { + UNIMPLEMENTED ("build the actual wiring descriptor based on given operation options"); + +// Bits config (FlagInfo::CODE); + size_t config = 13; /////////////////////////////////////////TODO +// return pImpl_->selector[config](); + } + // BlockAlloc > > >::fabricate(); + + +} // namespace engine diff --git a/src/proc/engine/nodewiring.hpp b/src/proc/engine/nodewiring.hpp new file mode 100644 index 000000000..6ad582efc --- /dev/null +++ b/src/proc/engine/nodewiring.hpp @@ -0,0 +1,90 @@ +/* + NODEWIRING.hpp - Implementation of the node network and operation control + + 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. + +*/ + + +#ifndef ENGINE_NODEWIRING_H +#define ENGINE_NODEWIRING_H + + +#include "proc/engine/procnode.hpp" + +#include +#include + + + +namespace engine { + + + class WiringFactory; + + namespace { class WiringFactoryImpl; } ////TODO: better use a named implementation namespace! (produces warings on gcc 4.3) + + + /** + * Actual implementation of the link between nodes, + * also acting as "track switch" for the execution path + * choosen while operating the node network for rendering. + * @param STATE Invocation state object controlling the + * behaviour of callDown() while rendering. + * @see StateAdapter + * @see NodeFactory + */ + template + class NodeWiring + : public WiringDescriptor + { + const uint siz_; + const uint nrO_; + + friend class WiringFactory; + + public: + virtual uint getNrI() const { return siz_ - nrO_; } + virtual uint getNrO() const { return nrO_; } + + + protected: + virtual BuffHandle + callDown (State& currentProcess, uint requiredOutputNr) const + { + STATE thisStep (currentProcess, *this); + return thisStep.retrieve (requiredOutputNr); // fetch or calculate results + } + + }; + + + + class WiringFactory + { + boost::scoped_ptr pImpl_; + + public: + WiringDescriptor& + operator() (uint nrOut, uint nrIn, bool cache); + }; + + + +} // namespace engine +#endif diff --git a/src/proc/engine/nodewiringconfig.hpp b/src/proc/engine/nodewiringconfig.hpp new file mode 100644 index 000000000..aac1ff7a1 --- /dev/null +++ b/src/proc/engine/nodewiringconfig.hpp @@ -0,0 +1,180 @@ +/* + NODEWIRINGCONFIG.hpp - Helper for representing and selecting the wiring case + + 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. + +*/ +/** @file nodewiringconfig.hpp + ** Sometimes we need to coose a different implementation for dealing with + ** some special cases. While for simple cases, just testing a flag or using a + ** switch statement will do the job, matters get more difficult when we have to + ** employ a completely different execution path for each of the different cases, + ** while using a set of common building blocks. + ** \par + ** In the Lumiera render engine, right on the critical path, we need some glue code + ** for invoking the predecessor nodes when pulling a given processing node. The actual + ** sequence is quite dependant on the specific situation each node is wired up, regarding + ** buffer allocation, cache querying and the possible support for GPU processing and + ** render farms. The solution is to define specialisations of a Strategy template + ** using the specific configuration as template argument. Based on these, we can + ** create a collection of factories, which in turn will build the internal wiring + ** for the individual ProcNode instances in accordance to the situation determined + ** for this node, expressed as a set of flags. As a net result, each node has an + ** indivudual configuration (as opposed to creating a lot of hand-written individual + ** ProcNode subclasses), but parts of this configuration assembly is done already at + ** compile time, allowing for additional checks by typing and for possible optimisation. + ** + ** @see proc::engine::config::Strategy + ** @see nodewiring.hpp + ** @see configflags.hpp + ** + */ +#ifndef ENGINE_NODEWIRINGCONFIG_H +#define ENGINE_NODEWIRINGCONFIG_H + + +#include "common/util.hpp" +#include "common/meta/configflags.hpp" + +#include +#include +#include + + +namespace engine { + namespace config { + + using lumiera::typelist::FlagInfo; + using util::contains; + + using lumiera::typelist::CONFIG_FLAGS_MAX; + + + /** + * Helper for fabricating ProcNode Wiring configurations. + * This object builds a table of factories, holding one factory + * for each possible node configuration. Provided with the desired + * configuration encoded as bits, the related factory can be invoked, + * thus producing a product object for the given configuration. + * + * \par implementation notes + * The actual factory class is templated, so it will be defined + * at the use site of ConfigSelector. Moreover, this factory + * usually expects an ctor argument, which will be fed through + * when creating the ConfigSelector instance. This is one of + * the reasons why we go through all these complicated factory + * building: this ctor argument usually brings in a reference + * to the actual memory allocator. Thus we have to rebuild the + * ConfigSelector each time we switch and rebuild the ProcNode + * factories, which in turn happens each time we use a new + * bulk allocation memory block -- typically for each separate + * segment of the Timeline and processing node graph. + * + * Now the selection of the possible flag configurations, for which + * Factory instances are created in the table, is governed by the + * type parameter of the ConfigSelector ctor. This type parameter + * needs to be a Typelist of Typelists, each representing a flag + * configuration. The intention is to to drive this selection by + * the use of template metaprogramming for extracting all + * currently defined StateProxy object configurations. + * @todo as the facories live only within the enclosed table (map) + * we could allocate them in-place. Unfortunately this is + * non-trivial, because the stl containers employ + * value semantics and thus do a copy even on insert. + * Thus, for now we use a shared_ptr to hold the factory + * heap allocated. + */ + template< template class Factory + , typename FUNC ///< common function type of all Factory instances + , typename PAR ///< ctor parameter of the Factories + > + class ConfigSelector + { + typedef boost::function FacFunction; + + template + struct FactoryHolder + : private FAC, + public FacFunction + { + FactoryHolder(PAR p) + : FAC(p), + FacFunction( static_cast(*this)) + { } + }; + + + typedef std::tr1::shared_ptr PFunc; + typedef std::map ConfigTable; + + ConfigTable possibleConfig_; ///< Table of factories + + /** Helper: a visitor usable with FlagInfo */ + struct FactoryTableBuilder + { + PAR ctor_param_; + ConfigTable& factories_; + + FactoryTableBuilder (ConfigTable& tab, PAR p) + : ctor_param_(p), + factories_(tab) { } + + + /* === visitation interface === */ + + typedef void Ret; + + template + void + visit (size_t code) + { + PFunc pFactory (new FactoryHolder > (ctor_param_)); + factories_[code] = pFactory; + } + + void done() {} + }; + + public: + template + ConfigSelector(CONFS const&, PAR factory_ctor_param) + { + FactoryTableBuilder buildTable(this->possibleConfig_, + factory_ctor_param ); + // store a new Factory instance + // for each possible Flag-Configuration + FlagInfo::accept (buildTable); + } + + FacFunction& + operator[] (size_t configFlags) ///< retrieve the factory corresponding to the given config + { + if (contains (possibleConfig_, configFlags)) + return *possibleConfig_[configFlags]; + else + throw lumiera::error::Invalid("ConfigSelector: No preconfigured factory for config-bits=" + +std::bitset(configFlags).to_string()); + } + }; + + + + } // namespace config + +} // namespace engine +#endif diff --git a/src/proc/engine/processor.cpp b/src/proc/engine/processor.cpp index c8a228845..38ed34c5d 100644 --- a/src/proc/engine/processor.cpp +++ b/src/proc/engine/processor.cpp @@ -22,8 +22,7 @@ #include "proc/engine/processor.hpp" -#include "proc/engine/exitnode.hpp" -#include "proc/stateproxy.hpp" +#include "proc/state.hpp" namespace engine { diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp index 164fa8bfa..3f0890c93 100644 --- a/src/proc/engine/processor.hpp +++ b/src/proc/engine/processor.hpp @@ -25,7 +25,7 @@ #define ENGINE_PROCESSOR_H #include "proc/lumiera.hpp" -#include "proc/stateproxy.hpp" +#include "proc/state.hpp" diff --git a/src/proc/engine/procnode.cpp b/src/proc/engine/procnode.cpp index 48e33c498..984c4dece 100644 --- a/src/proc/engine/procnode.cpp +++ b/src/proc/engine/procnode.cpp @@ -22,12 +22,14 @@ #include "proc/engine/procnode.hpp" +#include "proc/engine/nodefactory.hpp" -namespace engine - { +namespace engine { - /** */ + /** Storage for the (single, static) ProcNode factory object. + */ + NodeFactory ProcNode::create; } // namespace engine diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index ae210f96b..343c6a6e8 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -20,39 +20,137 @@ */ +/** @file procnode.hpp + ** Interface to the processing nodes and the render nodes network. + ** + ** Actually, there are three different interfaces to consider + ** - the ProcNode#pull is the invocation interface. It is call-style (easily callable by C) + ** - the builder interface, comprised by the NodeFactory and the WiringFactory. It's C++ (using templates) + ** - the actual processing function is supposed to be a C function; it uses a set of C functions + ** for accessing the frame buffers with the data to be processed. + ** + ** By using the builder interface, concrete node and wiring descriptor classes are created, + ** based on some templates. These concrete classes form the "glue" to tie the node network + ** together and contain much of the operation beahviour in a hard wired fashion. + ** + ** @see nodefactory.hpp + ** @see operationpoint.hpp + */ #ifndef ENGINE_PROCNODE_H #define ENGINE_PROCNODE_H -#include +#include "pre.hpp" +#include "proc/lumiera.hpp" +#include "proc/state.hpp" #include "proc/mobject/parameter.hpp" - -using std::vector; +#include -namespace engine - { - +namespace engine { + using std::vector; + using proc_interface::State; + + class ProcNode; + class NodeFactory; + + typedef ProcNode* PNode; + + template + struct RefArray + { + virtual E const& operator[] (uint i) const =0; + virtual ~RefArray() {} + }; + + /** + * Interface: Description of the input and output ports, + * processing function and predecessor nodes for a given ProcNode. + */ + class WiringDescriptor + { + public: + virtual ~WiringDescriptor() {} + + virtual uint getNrI() const =0; ///////////TODO: indeed need a virtual function?? + virtual uint getNrO() const =0; + + RefArray& out; + RefArray& in; + + typedef void (ProcFunc) (BuffHandle::PBuff, uint); + + ProcFunc* processFunction; + + protected: + WiringDescriptor (RefArray& o, + RefArray& i, + ProcFunc pFunc) + : out(o), in(i), + processFunction(pFunc) + { } + + /** the wiring-dependent part of the node operation. + * Includes the creation of a one-way state object on the stack + * holding the actual buffer pointers and issuing the recrusive pull() calls + * @see NodeWiring#callDown default implementation + */ + virtual BuffHandle callDown (State& currentProcess, uint requiredOutputNr) const =0; + + friend class ProcNode; + + }; + + + + /** * Key abstraction of the Render Engine: A Data processing Node */ class ProcNode { - protected: - typedef mobject::Parameter Param; - - /** The predecessor in a processing pipeline. - * I.e. a source to get data to be processed - */ - ProcNode * datasrc; - + typedef mobject::Parameter Param; //////TODO: just a placeholder for automation as of 6/2008 vector params; - + + const WiringDescriptor& wiringConfig_; + + protected: + ProcNode (WiringDescriptor const& wd) + : wiringConfig_(wd) + { } + + virtual ~ProcNode() {}; + + friend class NodeFactory; + + + + public: + static NodeFactory create; ///////TODO: really? probably we'll rather have a NodeFactory object in the builder... + + /** Engine Core operation: render and pull output from this node. + * On return, currentProcess will hold onto output buffer(s) + * containing the calculated result frames. In case this node + * calculates a multi channel output, only one channel can be + * retrieved by such a \c pull() call, but you can expect data + * of the other channels to be processed and fed to cache. + * @param currentProcess the current processing state for + * managing buffers and accessing current parameter values + * @param requiredOutputNr the output channel requested (in case + * this node delivers more than one output channel) + * @return handle to the buffer containing the calculated result. + */ + BuffHandle + pull (State& currentProcess, uint requiredOutputNr=0) const + { + return this->wiringConfig_.callDown (currentProcess, requiredOutputNr); + } + }; - + } // namespace engine #endif diff --git a/src/proc/engine/projector.hpp b/src/proc/engine/projector.hpp index 0908eec38..4e03c4cc2 100644 --- a/src/proc/engine/projector.hpp +++ b/src/proc/engine/projector.hpp @@ -37,7 +37,7 @@ namespace engine */ class Projector : public Trafo { - //////////// + ////////////TODO adapt ctor }; diff --git a/src/proc/engine/source.hpp b/src/proc/engine/source.hpp index 37af97841..3573f3e0b 100644 --- a/src/proc/engine/source.hpp +++ b/src/proc/engine/source.hpp @@ -40,7 +40,9 @@ namespace engine */ class Source : public ProcNode { - /////////////////TODO + Source (WiringDescriptor const& wd) + : ProcNode(wd) + { } }; diff --git a/src/proc/stateproxy.cpp b/src/proc/engine/stateproxy.cpp similarity index 81% rename from src/proc/stateproxy.cpp rename to src/proc/engine/stateproxy.cpp index f4125a41e..6e2566d3e 100644 --- a/src/proc/stateproxy.cpp +++ b/src/proc/engine/stateproxy.cpp @@ -1,5 +1,5 @@ /* - StateProxy - Key Interface representing a render process and encapsulating state + StateProxy - Encapsulation of the state corresponding to a render calculation Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,14 +21,12 @@ * *****************************************************/ -#include "proc/stateproxy.hpp" -#include "proc/frame.hpp" +#include "proc/engine/stateproxy.hpp" -namespace proc_interface - { +namespace engine { /** */ -} // namespace proc_interface +} // namespace engine diff --git a/src/proc/stateproxy.hpp b/src/proc/engine/stateproxy.hpp similarity index 73% rename from src/proc/stateproxy.hpp rename to src/proc/engine/stateproxy.hpp index 7c338bd1d..ff7d107d3 100644 --- a/src/proc/stateproxy.hpp +++ b/src/proc/engine/stateproxy.hpp @@ -1,5 +1,5 @@ /* - STATEPROXY.hpp - Key Interface representing a render process and encapsulating state + STATEPROXY.hpp - Encapsulation of the state corresponding to a render calculation Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,25 +21,26 @@ */ -#ifndef PROC_INTERFACE_STATEPROXY_H -#define PROC_INTERFACE_STATEPROXY_H - -#include "proc/frame.hpp" +#ifndef ENGINE_STATEPROXY_H +#define ENGINE_STATEPROXY_H +#include "proc/state.hpp" + + +namespace engine { -namespace proc_interface - { class StateProxy + : public proc_interface::State { protected: - Frame * currFrame; - + virtual State& getCurrentImplementation () { return *this; } + }; -} // namespace proc_interface +} // namespace engine #endif diff --git a/src/proc/engine/trafo.hpp b/src/proc/engine/trafo.hpp index 8d2155661..166154674 100644 --- a/src/proc/engine/trafo.hpp +++ b/src/proc/engine/trafo.hpp @@ -42,9 +42,25 @@ namespace engine */ class Trafo : public ProcNode { - /////////// + protected: + Trafo (WiringDescriptor const& wd) + : ProcNode(wd) + { } + + friend class NodeFactory; + + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; }; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + } // namespace engine diff --git a/src/proc/engine/vframe.cpp b/src/proc/engine/vframe.cpp deleted file mode 100644 index 180faca70..000000000 --- a/src/proc/engine/vframe.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - VFrame - a buffer holding a Video frame for the render process - - 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 "proc/engine/vframe.hpp" - -namespace engine - { - - /** */ - - - -} // namespace engine diff --git a/src/proc/engine/vframe.hpp b/src/proc/engine/vframe.hpp deleted file mode 100644 index 6b1e8153b..000000000 --- a/src/proc/engine/vframe.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - VFRAME.hpp - a buffer holding a Video frame for the render process - - 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. - -*/ - - -#ifndef ENGINE_VFRAME_H -#define ENGINE_VFRAME_H - -#include "proc/frame.hpp" - - - -namespace engine - { - - - class VFrame : public proc_interface::Frame - { - /////////////////////// - }; - -} // namespace engine -#endif diff --git a/src/proc/engine/vrender.cpp b/src/proc/engine/vrender.cpp deleted file mode 100644 index 2bed41099..000000000 --- a/src/proc/engine/vrender.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - VRender - Representation of a Video render process - - 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 "proc/engine/vrender.hpp" - -namespace engine - { - - /** */ - - - - } // namespace engine diff --git a/src/proc/lumiera.hpp b/src/proc/lumiera.hpp index b90a692ad..49822b469 100644 --- a/src/proc/lumiera.hpp +++ b/src/proc/lumiera.hpp @@ -33,12 +33,10 @@ #include "common/p.hpp" #include "common/util.hpp" #include "common/lumitime.hpp" -#include "common/error.hpp" //< pulls in NoBug via nobugcfg.hpp +#include "common/error.hpp" ///< pulls in NoBug via nobugcfg.hpp #include "lib/appconfig.hpp" -/** - * The namespace of all lumiera classes. - */ + namespace lumiera { /* additional global configuration goes here... */ diff --git a/src/proc/mobject/builder/applicablebuildertargettypes.hpp b/src/proc/mobject/builder/applicablebuildertargettypes.hpp index e51fa1251..b02fb9d45 100644 --- a/src/proc/mobject/builder/applicablebuildertargettypes.hpp +++ b/src/proc/mobject/builder/applicablebuildertargettypes.hpp @@ -55,7 +55,7 @@ namespace mobject { * common selection of types to be handled by any such builder tool. * The actual BuilderTool impl should inherit from this template by * feeding back its type (CRTP), this causes a dispatcher table entry - * be generated for this concrete BuilderTool implementation. + * to be generated for this concrete BuilderTool implementation. */ template struct ApplicableBuilderTargetTypes diff --git a/src/proc/mobject/builder/mould.hpp b/src/proc/mobject/builder/mould.hpp new file mode 100644 index 000000000..be29f2b21 --- /dev/null +++ b/src/proc/mobject/builder/mould.hpp @@ -0,0 +1,87 @@ +/* + MOULD.hpp - builder tool kit for the basic building situations + + 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. + +*/ + + +#ifndef MOBJECT_BUILDER_MOULD_H +#define MOBJECT_BUILDER_MOULD_H + + +#include "proc/asset/procpatt.hpp" +#include "proc/mobject/builder/operationpoint.hpp" + +#include + +namespace mobject { + namespace builder { + + using std::vector; + using asset::PProcPatt; + using lumiera::Symbol; + + + /** + * Interface: a workbench-like tool used by the builder + * for wiring up a specific building situation, followed by + * the application/execution of a single building step. Mould is + * conceived as the passive part, while usually the ProcPatt plays + * the role of the active counterpart. By means of the Mould interface, + * the specifics of a build situation are abstracted away, thus allowing + * the processing pattern to be defined as working on symbolic locations. + * Most commonly this is "current", denoting the render node just being built. + *
  • PipeMould supports attaching an effect to a pipe
  • + *
  • combining pipes via a transition is done by a CombiningMould
  • + *
  • a SourceChainMould allows to start out from a source reader and build a clip
  • + *
  • wiring general connections is supported by the WiringMould
  • + *
+ * @see ToolFactory + * @see NodeCreatorTool + */ + class Mould + { + public: + vector operate (); + + OperationPoint& getLocation (Symbol locationID); + }; + + + class PipeMould : public Mould + { + }; + + class CombiningMould : public Mould + { + }; + + class SourceChainMould : public Mould + { + }; + + class WiringMould : public Mould + { + }; + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/src/proc/mobject/builder/nodecreatertool.cpp b/src/proc/mobject/builder/nodecreatortool.cpp similarity index 96% rename from src/proc/mobject/builder/nodecreatertool.cpp rename to src/proc/mobject/builder/nodecreatortool.cpp index 93362ef25..ed24e36c2 100644 --- a/src/proc/mobject/builder/nodecreatertool.cpp +++ b/src/proc/mobject/builder/nodecreatortool.cpp @@ -21,7 +21,7 @@ * *****************************************************/ -#include "proc/mobject/builder/nodecreatertool.hpp" +#include "proc/mobject/builder/nodecreatortool.hpp" #include "proc/mobject/session/clip.hpp" #include "proc/mobject/session/effect.hpp" #include "proc/mobject/session/auto.hpp" diff --git a/src/proc/mobject/builder/nodecreatertool.hpp b/src/proc/mobject/builder/nodecreatortool.hpp similarity index 100% rename from src/proc/mobject/builder/nodecreatertool.hpp rename to src/proc/mobject/builder/nodecreatortool.hpp diff --git a/src/proc/mobject/builder/operationpoint.hpp b/src/proc/mobject/builder/operationpoint.hpp new file mode 100644 index 000000000..f72d9c711 --- /dev/null +++ b/src/proc/mobject/builder/operationpoint.hpp @@ -0,0 +1,73 @@ +/* + OPERATIONPOINT.hpp - abstraction representing the point where to apply a build instruction + + 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. + +*/ + + +#ifndef MOBJECT_BUILDER_OPERATIONPOINT_H +#define MOBJECT_BUILDER_OPERATIONPOINT_H + +#include "proc/engine/procnode.hpp" +#include "common/query.hpp" + +#include +#include + + +namespace mobject { + namespace builder { + + using std::vector; + using std::string; + + /** + * A point in the render node network under construction. + * By means of this unspecific reference, a ProcPatt is able + * to deal with this location and to execute a single elementary + * building operation denoted by a BuildInstruct at this point. + * Usually, the actual point is retrieved from a Mould + */ + class OperationPoint + { + typedef engine::PNode PNode; + + vector refPoint_; + const string streamID_; + + public: + /** create node(s) corresponding to the given Processor-Asset + * and wire them as a successor to this OperationPoint; then + * move this point to refer to the resulting new exit node(s) + */ + void attach (asset::PProc const&); + + /** connect the output this OperationPoint referes such as to + * connect or combine with the input of the already existing + * nodes accessible via the target OperationPoint. + */ + void join (OperationPoint& target); + }; + + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/src/proc/mobject/controller/renderstate.cpp b/src/proc/mobject/builder/toolfactory.cpp similarity index 79% rename from src/proc/mobject/controller/renderstate.cpp rename to src/proc/mobject/builder/toolfactory.cpp index 98ca2ccd1..8e1b14631 100644 --- a/src/proc/mobject/controller/renderstate.cpp +++ b/src/proc/mobject/builder/toolfactory.cpp @@ -1,5 +1,5 @@ /* - RenderState - renderengine state manager + ToolFactory - supply of Tool implementations for the Builder Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,24 +21,22 @@ * *****************************************************/ -#include "proc/mobject/controller/renderstate.hpp" - +#include "proc/mobject/builder/toolfactory.hpp" namespace mobject { - namespace controller + namespace builder { - StateProxy& - RenderState::getStateProxy () + BuilderTool & + ToolFactory::configure () { - //////////////TODO } - } // namespace mobject::controller + } // namespace mobject::builder } // namespace mobject diff --git a/src/proc/engine/vrender.hpp b/src/proc/mobject/builder/toolfactory.hpp similarity index 53% rename from src/proc/engine/vrender.hpp rename to src/proc/mobject/builder/toolfactory.hpp index c6a34bda2..c796d5c9e 100644 --- a/src/proc/engine/vrender.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -1,5 +1,5 @@ /* - VRENDER.hpp - Representation of a Video render process + TOOLFACTORY.hpp - supply of Tool implementations for the Builder Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,27 +21,35 @@ */ -#ifndef ENGINE_VRENDER_H -#define ENGINE_VRENDER_H +#ifndef MOBJECT_BUILDER_TOOLFACTORY_H +#define MOBJECT_BUILDER_TOOLFACTORY_H -#include "proc/stateproxy.hpp" +#include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/builder/mould.hpp" -namespace engine +namespace mobject { - - - /** - * Representation of a Video render process. - * (Encapsulates the video buffers for the actual calculations) - */ - class VRender : public proc_interface::StateProxy + namespace builder { - ///////////// - }; + + + /** + * provides the builder with the necessary, preconfigured tools. + * Dedicated to a single build process, it holds the internal state + * of this process and thus serves to coordinate and link together all + * the individual parts fabricated by using the various tools. + */ + class ToolFactory + { + public: + BuilderTool & configure () ; + }; -} // namespace engine + } // namespace mobject::builder + +} // namespace mobject #endif diff --git a/src/proc/mobject/controller/renderstate.hpp b/src/proc/mobject/controller/renderstate.hpp index c547772ea..833e2d347 100644 --- a/src/proc/mobject/controller/renderstate.hpp +++ b/src/proc/mobject/controller/renderstate.hpp @@ -24,7 +24,7 @@ #ifndef MOBJECT_CONTROLLER_RENDERSTATE_H #define MOBJECT_CONTROLLER_RENDERSTATE_H -#include "proc/stateproxy.hpp" +#include "proc/state.hpp" @@ -33,7 +33,7 @@ namespace mobject namespace controller { - typedef proc_interface::StateProxy StateProxy; + typedef proc_interface::State State; /** @@ -42,11 +42,12 @@ namespace mobject * The provided StateProxy serves to hold any mutalbe state used * in the render process, so the rest of the render engine * can be stateless. + * @todo probably the state management will work different (6/08) */ class RenderState { public: - StateProxy& getStateProxy () ; + State& getRenderProcess () ; }; diff --git a/src/proc/mobject/session/defsregistry.hpp b/src/proc/mobject/session/defsregistry.hpp index 7d7589110..64f84ab32 100644 --- a/src/proc/mobject/session/defsregistry.hpp +++ b/src/proc/mobject/session/defsregistry.hpp @@ -52,7 +52,7 @@ namespace mobject using boost::lambda::_1; using boost::lambda::var; - namespace // Implementation details + namespace // Implementation details //////////////////TODO better a named implementation namespace (avoids warnings on gcc 4.3) { struct TableEntry { @@ -159,7 +159,7 @@ namespace mobject template size_t Slot::index (0); - } + } // (End) impl namespace /** diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index 427385194..e1a7a5695 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -28,8 +28,8 @@ -namespace asset - { +namespace asset { + class Clip; class Media; class Track; @@ -37,10 +37,9 @@ namespace asset } -namespace mobject - { - namespace session - { +namespace mobject { + namespace session { + class Clip; class Track; class Effect; @@ -57,10 +56,10 @@ namespace mobject public: - Placement operator() (const asset::Clip&, const asset::Media&); - Placement operator() (const asset::Clip&, vector); + Placement operator() (asset::Clip const&, asset::Media const&); + Placement operator() (asset::Clip const&, vector); Placement operator() (PTrackAsset&); - Placement operator() (const asset::Effect&); + Placement operator() (asset::Effect const&); }; diff --git a/src/proc/frame.cpp b/src/proc/state.cpp similarity index 80% rename from src/proc/frame.cpp rename to src/proc/state.cpp index 46ad06950..fa9f32dc3 100644 --- a/src/proc/frame.cpp +++ b/src/proc/state.cpp @@ -1,5 +1,5 @@ /* - Frame - Key Abstraction: render process and buffer holding frame data. + State - Key Interface representing a render process and encapsulating state Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,11 +21,12 @@ * *****************************************************/ -#include "proc/frame.hpp" +#include "proc/state.hpp" namespace proc_interface { + ////////////////////////////////TODO: State is a high -level interface, so can we get rid of this implementation file? /** */ diff --git a/src/proc/state.hpp b/src/proc/state.hpp new file mode 100644 index 000000000..cd98a39b8 --- /dev/null +++ b/src/proc/state.hpp @@ -0,0 +1,101 @@ +/* + STATE.hpp - Key Interface representing a render process and encapsulating state + + 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. + +*/ + + +#ifndef PROC_INTERFACE_STATE_H +#define PROC_INTERFACE_STATE_H + + +#include "pre.hpp" + +#include "proc/lumiera.hpp" +#include "common/frameid.hpp" +#include "proc/engine/buffhandle.hpp" + +#include + + +namespace engine { + + using lumiera::FrameID; + + class StateAdapter; + class BuffTableStorage; + + class State + { + protected: + virtual ~State() {}; + + /** resolves to the State object currently "in charge". + * Intended as a performance shortcut to avoid calling + * up through a chain of virtual functions when deep down + * in chained ProcNode::pull() calls. This allows derived + * classes to proxy the state inteface. + */ + virtual State& getCurrentImplementation () =0; + + friend class engine::StateAdapter; + + public: + /** allocate a new writable buffer with type and size according to + * the BufferDescriptor. The actual provider of this buffer depends + * on the State implementation; it could be a temporary, located in + * the cache, used for feeding calculated frames over a network, etc. + * @return a BuffHandle encapsulating the information necessary to get + * at the actual buffer adress and for releasing the buffer. + */ + virtual BuffHandle allocateBuffer (BufferDescriptor const&) =0; + + /** resign control of the buffer denoted by the handle */ + virtual void releaseBuffer (BuffHandle&) =0; + + /** declare the data contained in the Buffer to be ready. + * The caller is required to restrain itself from modifying the data + * afterwards, as this buffer now can be used (readonly) by other + * calculation processes in parallel. + */ + virtual void is_calculated (BuffHandle const&) =0; + + /** try to fetch an existing buffer containing the denoted frame from + * a cache or similar backing system (e.g. peer over the network). + * @return either a handle to a readonly buffer, or a null handle + * @note the client is resposible for not modifying the provided data + */ + virtual BuffHandle fetch (FrameID const&) =0; + + /** necessary for creating a local BuffTableChunk */ + virtual BuffTableStorage& getBuffTableStorage() =0; + + }; + +} // namespace engine + + + +namespace proc_interface { + + using engine::State; + + +} // namespace proc_interface +#endif diff --git a/src/tool/try.cpp b/src/tool/try.cpp index 85a3286a0..3f51bcaf6 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -10,234 +10,111 @@ // 4/08 - comparison operators on shared_ptr // 4/08 - conversions on the value_type used for boost::any // 5/08 - how to guard a downcasting access, so it is compiled in only if the involved types are convertible +// 7/08 - combining partial specialisation and subclasses #include #include #include - -#include -#include -#include -#include -#include -#include - +#include using std::string; using std::cout; using std::ostream; +using boost::format; - using boost::remove_pointer; - using boost::remove_reference; - using boost::is_convertible; - using boost::is_polymorphic; - using boost::is_base_of; - using boost::enable_if; - - template - struct can_cast : boost::false_type {}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - - template - struct has_RTTI - { - typedef typename remove_pointer< - typename remove_reference::type>::type TPlain; +#include +using boost::enable_if; +#include +using boost::is_base_of; +#include +#include + + +#include "common/meta/generator.hpp" +using lumiera::typelist::NullType; +using lumiera::typelist::Node; +using lumiera::typelist::Types; + + + namespace { + + boost::format fmt ("<%2i>"); + + /** constant-wrapper type for debugging purposes, + * usable for generating lists of distinghishable types + */ + template + struct Num + { + enum{ VAL=I }; + static string str () { return boost::str (fmt % I); } + Num() + { + cout << Num::str(); + } + }; + - enum { value = is_polymorphic::value }; - }; - template - struct use_dynamic_downcast + template class _CandidateTemplate_> + class Instantiation { - enum { value = can_cast::value - && has_RTTI::value - && has_RTTI::value - }; - }; - - template - struct use_static_downcast - { - enum { value = can_cast::value - && ( !has_RTTI::value - || !has_RTTI::value - ) - }; - }; - - template - struct use_conversion - { - enum { value = is_convertible::value - && !( use_static_downcast::value - ||use_dynamic_downcast::value - ) - }; - }; - - - template - struct EmptyVal - { - static X create() + template + struct If_possibleArgument : _CandidateTemplate_ { - cout << " NULL() " << __PRETTY_FUNCTION__ <<"\n"; - return X(); - } - }; - template - struct EmptyVal - { - static X*& create() - { - cout << " NULL & " << __PRETTY_FUNCTION__ <<"\n"; - static X* null(0); - return null; - } - }; - - - template - struct NullAccessor - { - typedef RET Ret; + typedef void Type; + }; + + public: + + template + struct Test + : boost::false_type {}; + + template + struct Test::Type > + : boost::true_type {}; - static RET access (...) { return ifEmpty(); } - static RET ifEmpty () { return EmptyVal::create(); } - }; - - template - struct AccessCasted : NullAccessor - { - using NullAccessor::access; - - template - static typename enable_if< use_dynamic_downcast, TAR>::type - access (ELM& elem) - { - cout << " dynamic " << __PRETTY_FUNCTION__ <<"\n"; - return dynamic_cast (elem); - } - - template - static typename enable_if< use_static_downcast, TAR>::type - access (ELM& elem) - { - cout << " static " << __PRETTY_FUNCTION__ <<"\n"; - return static_cast (elem); - } - - template - static typename enable_if< use_conversion, TAR>::type - access (ELM& elem) - { - cout << " convert " << __PRETTY_FUNCTION__ <<"\n"; - return elem; - } - }; + + } + + struct Boing { typedef boost::true_type is_defined; }; + + template struct Zoing ; + + template<> struct Zoing<2> : Boing { enum{wau = 2}; }; + template<> struct Zoing<5> : Boing { enum{wau = 5}; }; - - - -struct B {}; -struct D : B {}; - -struct E : D + typedef char yes_type; + struct no_type { - virtual ~E() {}; + char padding[8]; }; -struct F : E {}; + template + yes_type check(typename U::is_defined *); + template + no_type check(...); -ostream& operator<< (ostream& s, const B& b) { return s << "B{} adr="<<&b; } -ostream& operator<< (ostream& s, const D& d) { return s << "D{} adr="<<&d; } -ostream& operator<< (ostream& s, const E& e) { return s << "E{} adr="<<&e; } -ostream& operator<< (ostream& s, const F& f) { return s << "F{} adr="<<&f; } - + int main (int argc, char* argv[]) { NOBUG_INIT; - D d; - D* pD =&d; - B* pB =pD; - D& rD = *pD; - B& rB = *pB; - - D*& rpD = pD; - B*& rpB = pB; - - F f; - E& rE = f; - E* pE = &f; - D* pDE = pE; - - cout << "is_base_of = " << is_base_of::value << "\n"; - cout << "is_base_of = " << is_base_of::value << "\n"; - cout << "is_base_of = " << is_base_of::value << "\n"; - - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - - cout << "can_cast = " << can_cast::value << "\n"; - cout << "can_cast = " << can_cast::value << "\n"; - - cout << "has_RTTI = " << has_RTTI::value << "\n"; - cout << "has_RTTI = " << has_RTTI::value << "\n"; - cout << "has_RTTI = " << has_RTTI::value << "\n"; + typedef Zoing<2> Z2; + typedef Zoing<3> Z3; + typedef Zoing<5> Z5; + + cout << sizeof(check(0)) << " / " + << sizeof(check(0)) << " / " + << sizeof(check(0)) ; - cout << "use_dynamic_downcast = " << use_dynamic_downcast::value << "\n"; - cout << "use_static_downcast = " << use_static_downcast::value << "\n"; - cout << "use_conversion = " << use_conversion::value << "\n"; - - cout << "use_static_downcast = " << use_static_downcast::value << "\n"; - cout << "use_static_downcast = " << use_static_downcast::value << "\n"; - cout << "use_dynamic_downcast = " << use_dynamic_downcast::value << "\n"; - - - cout << "Access(D as D&) --->" << AccessCasted::access(d) << "\n"; - cout << "Access(D& as D&) --->" << AccessCasted::access(rD) << "\n"; - cout << "Access(B& as D&) --->" << AccessCasted::access(rB) << "\n"; - cout << "Access(D* as D*) --->" << AccessCasted::access(pD) << "\n"; - cout << "Access(B* as D*) --->" << AccessCasted::access(pB) << "\n"; - cout << "Access(D*& as D*&) --->" << AccessCasted::access(rpD) << "\n"; - cout << "Access(B*& as D*&) --->" << AccessCasted::access(rpB) << "\n"; - - cout << "Access(D as B&) --->" << AccessCasted::access(d) << "\n"; - cout << "Access(D& as B&) --->" << AccessCasted::access(rD) << "\n"; - cout << "Access(B& as B&) --->" << AccessCasted::access(rB) << "\n"; - cout << "Access(D* as B*) --->" << AccessCasted::access(pD) << "\n"; - cout << "Access(B* as B*) --->" << AccessCasted::access(pB) << "\n"; - cout << "Access(D*& as B*&) --->" << AccessCasted::access(rpD) << "\n"; - cout << "Access(B*& as B*&) --->" << AccessCasted::access(rpB) << "\n"; - - cout << "Access(D as E&) --->" << AccessCasted::access(d) << "\n"; - cout << "Access(E& as F&) --->" << AccessCasted::access(rE) << "\n"; - cout << "Access(D(E)* as E*) --->" << AccessCasted::access(pDE) << "\n"; - cout << "Access(D(E)* as F*) --->" << AccessCasted::access(pDE) << "\n"; - cout << "Access(E* as F*) --->" << AccessCasted::access(pE) << "\n"; - cout << "\ngulp\n"; diff --git a/tests/50components.tests b/tests/50components.tests index ae15f37c3..417b094ab 100644 --- a/tests/50components.tests +++ b/tests/50components.tests @@ -50,6 +50,109 @@ out: Standard Cmdlineformat:one two END +TEST "ConfigFlags_test" ConfigFlags_test <- +out: Conf2 :-<2>- +out: Conf3 :-<3>- +out: Conf4 :-<2>-<4>- +out: AllFlags :-<1>-<2>-<3>-<4>- +out: __________________________ +out: __________________________ check_flags() +out: Flags1 :-<2>-<4>- +out: Flags2 :-<2>-<4>- +out: SimpleConfig_defined_by_Typelist :-<1>- +out: AnotherConfig_defined_by_Typelist :-<1>-<2>-<3>-<4>- +out: __________________________ +out: __________________________ check_instantiation() +out: defined Conf0? ---> 0 +out: defined Conf1? ---> 1 +out: defined Conf2? ---> 1 +out: defined Conf3? ---> 1 +out: defined Conf4? ---> 1 +out: defined Trash? ---> 0 +out: __________________________ +out: __________________________ check_filter() +out: SomeFlagsets : +out: +---<1>-<3>-+ +out: +---<2>-<4>-+- +out: Configs_defined_by_Flagsets : +out: +-Conf-[-<1>-<3>-] +out: +-Conf-[-<2>-<4>-]- +out: Filter_possible_Configs : +out: +-Conf-[-<2>-<4>-]- +out: AllFlagCombinations : +out: +---<1>-<2>-<3>-<4>-<·>-+ +out: +---<1>-<2>-<3>-<·>-+ +out: +---<1>-<2>-<4>-<·>-+ +out: +---<1>-<2>-<·>-+ +out: +---<1>-<3>-<4>-<·>-+ +out: +---<1>-<3>-<·>-+ +out: +---<1>-<4>-<·>-+ +out: +---<1>-<·>-+ +out: +---<2>-<3>-<4>-<·>-+ +out: +---<2>-<3>-<·>-+ +out: +---<2>-<4>-<·>-+ +out: +---<2>-<·>-+ +out: +---<3>-<4>-<·>-+ +out: +---<3>-<·>-+ +out: +---<4>-<·>-+ +out: +---<·>-+- +out: ListAllConfigs : +out: +-Conf-[-<1>-<2>-<3>-<4>-] +out: +-Conf-[-<1>-<2>-<3>-] +out: +-Conf-[-<1>-<2>-<4>-] +out: +-Conf-[-<1>-<2>-] +out: +-Conf-[-<1>-<3>-<4>-] +out: +-Conf-[-<1>-<3>-] +out: +-Conf-[-<1>-<4>-] +out: +-Conf-[-<1>-] +out: +-Conf-[-<2>-<3>-<4>-] +out: +-Conf-[-<2>-<3>-] +out: +-Conf-[-<2>-<4>-] +out: +-Conf-[-<2>-] +out: +-Conf-[-<3>-<4>-] +out: +-Conf-[-<3>-] +out: +-Conf-[-<4>-] +out: +-Conf-[-]- +out: Filter_all_possible_Configs : +out: +-Conf-[-<1>-] +out: +-Conf-[-<2>-<3>-] +out: +-Conf-[-<2>-<4>-] +out: +-Conf-[-<2>-] +out: +-Conf-[-<3>-]- +out: __________________________ +out: __________________________ check_FlagInfo() +out: Flags1 :-<1>-<3>- +out: max bit : 3 +out: binary code: 10 +out: SomeConfigs : +out: +-Conf-[-<1>-<3>-] +out: +-Conf-[-<2>-<4>-]- +out: max bit in [SomeConfigs] : 4 +out: TestVisitor application: +out: visit(code=10) --> +out: +-Conf-[-<1>-<3>-]- +out: visit(code=20) --> +out: +-Conf-[-<2>-<4>-]- +out: __________________________ +out: __________________________ check_ConfigSelector() +out: Possible_Configs : +out: +-Conf-[-<1>-] +out: +-Conf-[-<2>-<3>-] +out: +-Conf-[-<2>-<4>-] +out: +-Conf-[-<2>-] +out: +-Conf-[-<3>-]- +out: Flag-code = 2 ConfigSelector() ---> 1010 +out: Flag-code = 12 ConfigSelector() ---> 1023 +out: Flag-code = 20 ConfigSelector() ---> 1024 +out: Flag-code = 4 ConfigSelector() ---> 1020 +out: Flag-code = 8 ConfigSelector() ---> 1030 +out: LUMIERA_ERROR_INVALID:invalid input or parameters (ConfigSelector: No preconfigured factory for config-bits=10111). +return: 0 +END + + TEST "CustomSharedPtr_test" CustomSharedPtr_test < > out: ctor DoIt > out: ctor DoIt > @@ -241,6 +344,106 @@ return: 0 END +TEST "TypeListManipl_test" TypeListManipl_test <-<2>-<3>- +out: List2 :-<5>-<6>-<7>- +out: Added2 :-<3>-<4>-<5>- +out: Append1 :- +out: Append2 :-<11>-<22>- +out: Append3 :-<111>- +out: Append4 :-<222>- +out: Append5 :-<1>-<2>-<3>- +out: Append6 :-<5>-<6>-<7>- +out: Append7 :-<111>-<5>-<6>-<7>- +out: Append8 :-<1>-<2>-<3>-<222>- +out: Append9 :-<1>-<2>-<3>-<5>-<6>-<7>- +out: FilterEven :-<2>-<6>- +out: Prefix1 : +out: +---<11>-<22>-+- +out: Prefix2 : +out: +---<101>-<1>-+ +out: +---<101>-<2>-+ +out: +---<101>-<3>-+- +out: Prefix3 : +out: +---<1>-+ +out: +---<2>-+ +out: +---<3>-+- +out: Prefix4 : +out: +---<111>-<1>-<2>-<3>-+ +out: +---<111>-<0>-+ +out: +---<111>-<5>-<6>-<7>-+- +out: Prefix5 : +out: +---<1>-<2>-<3>-<5>-+ +out: +---<1>-<2>-<3>-<6>-+ +out: +---<1>-<2>-<3>-<7>-+- +out: Prefix6 : +out: +---<1>-<2>-<3>-<1>-<2>-<3>-+ +out: +---<1>-<2>-<3>-<0>-+ +out: +---<1>-<2>-<3>-<5>-<6>-<7>-+- +out: Dist1 : +out: +---<11>-<1>-+ +out: +---<11>-<2>-+ +out: +---<11>-<3>-+- +out: Dist2 : +out: +---<11>-<0>-+ +out: +---<22>-<0>-+ +out: +---<33>-<0>-+- +out: Dist3 : +out: +---<11>-<1>-+ +out: +---<11>-<2>-+ +out: +---<11>-<3>-+ +out: +---<22>-<1>-+ +out: +---<22>-<2>-+ +out: +---<22>-<3>-+ +out: +---<33>-<1>-+ +out: +---<33>-<2>-+ +out: +---<33>-<3>-+- +out: Dist4 : +out: +---<11>-<1>-<2>-<3>-+ +out: +---<11>-<5>-<6>-<7>-+ +out: +---<22>-<1>-<2>-<3>-+ +out: +---<22>-<5>-<6>-<7>-+ +out: +---<33>-<1>-<2>-<3>-+ +out: +---<33>-<5>-<6>-<7>-+- +out: Down :-<11>-<10>-<9>-<8>-<7>-<6>-<5>-<4>-<3>-<2>-<1>-<0>- +out: Combi : +out: +---<1>-<2>-<3>-<·>-+ +out: +---<1>-<2>-<2>-<·>-+ +out: +---<1>-<2>-<1>-<·>-+ +out: +---<1>-<2>-<0>-<·>-+ +out: +---<1>-<1>-<3>-<·>-+ +out: +---<1>-<1>-<2>-<·>-+ +out: +---<1>-<1>-<1>-<·>-+ +out: +---<1>-<1>-<0>-<·>-+ +out: +---<1>-<0>-<3>-<·>-+ +out: +---<1>-<0>-<2>-<·>-+ +out: +---<1>-<0>-<1>-<·>-+ +out: +---<1>-<0>-<0>-<·>-+ +out: +---<0>-<2>-<3>-<·>-+ +out: +---<0>-<2>-<2>-<·>-+ +out: +---<0>-<2>-<1>-<·>-+ +out: +---<0>-<2>-<0>-<·>-+ +out: +---<0>-<1>-<3>-<·>-+ +out: +---<0>-<1>-<2>-<·>-+ +out: +---<0>-<1>-<1>-<·>-+ +out: +---<0>-<1>-<0>-<·>-+ +out: +---<0>-<0>-<3>-<·>-+ +out: +---<0>-<0>-<2>-<·>-+ +out: +---<0>-<0>-<1>-<·>-+ +out: +---<0>-<0>-<0>-<·>-+- +out: OnOff : +out: +---<1>-<2>-<3>-<·>-+ +out: +---<1>-<2>-<·>-+ +out: +---<1>-<3>-<·>-+ +out: +---<1>-<·>-+ +out: +---<2>-<3>-<·>-+ +out: +---<2>-<·>-+ +out: +---<3>-<·>-+ +out: +---<·>-+- +return: 0 +END + + TEST "VisitingTool_test" VisitingTool_test < + + 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. + +* *****************************************************/ + + +/** @file configflagstest.cpp + ** \par build a type representing a single configuration defined by a set of flags + ** + ** The semi-automatic assembly of processing node invocation code utilizes some + ** metaprogramming to generate a factory, which in turn produces node wiring objects + ** according to the configuration to be used for the corresponding ProcNode. This relies on + ** generating a distinct type based on a given set of configuration flags, + ** which is covered by this test. + ** + ** @see configflags.hpp + ** @see typelistmanip.hpp + ** @see nodewiringconfig.hpp real world usage example + ** + */ + + +#include "common/test/run.hpp" +#include "common/meta/util.hpp" +#include "common/meta/generator.hpp" +#include "common/meta/typelistutil.hpp" +#include "common/meta/configflags.hpp" +#include "meta/typelistdiagnostics.hpp" +#include "proc/engine/nodewiringconfig.hpp" +#include "common/util.hpp" + +#include +#include + +using ::test::Test; +using std::string; +using std::cout; + + +namespace lumiera { + namespace typelist { + namespace test { + + + namespace { // internal definitions + + enum Cases + { ONE = 1 + , TWO + , THR + , FOU + , NUM_Cases = FOU + + , NOT_SET = 0 + }; + + + + /* === Test data === */ + typedef Config<> Conf0; + typedef Config Conf1; + typedef Config Conf2; + typedef Config Conf3; + typedef Config Conf4; + + typedef Flags::Tuple Flags1; + typedef Flags::Tuple Flags2; + typedef Types SomeFlagsets; + + typedef Flags::Tuple AllFlags; + typedef CombineFlags AllFlagCombinations; + + + + /** a type which is only partially defined, for some configs. + * In ConfigFlags_test::check_filter() we use the metaprogramming machinery + * to figure out all possible configs for which \c struct Maybe is defined. + * (for this to work, the "defined" specialisations need to provide a + * typedef \c is_defined ) + */ + template struct Maybe; + + struct Indeed { typedef Yes_t is_defined; }; + template<> struct Maybe : Indeed { enum{ CODE = 10 }; }; + template<> struct Maybe : Indeed { enum{ CODE = 30 }; }; + + template + struct Maybe > + { + typedef Yes_t is_defined; + + enum{ CODE = 20 + Fl }; + }; + + + } // (End) internal defs + +#define PRINT_DELIMITER(TITLE) \ + cout << "__________________________\n" \ + "__________________________ " \ + << STRINGIFY(TITLE) << "\n"; + + + + + + /************************************************************************** + * @test check the handling of types representing a specific configuration. + * Basically, this is a bitset like feature, but working on types + * instead of runtime values. The Goal is to detect automatically + * all possible defined specialisations of some template based on + * such configuration-tuples. This allows us to assemble the glue code + * for pulling data from processing nodes out of small building blocks + * in all possible configuraions. + */ + class ConfigFlags_test : public Test + { + virtual void run(Arg arg) + { + check_testdata (); + check_flags(); + check_instantiation (); + check_filter (); + check_FlagInfo (); + check_ConfigSelector (); + } + + + void check_testdata () + { + DISPLAY (Conf0); + DISPLAY (Conf1); + DISPLAY (Conf2); + DISPLAY (Conf3); + DISPLAY (Conf4); + + DISPLAY (AllFlags); + } + + + /** @test conversion between list-of-flags and a config-type in both directions */ + void check_flags () + { + PRINT_DELIMITER (check_flags()); + + typedef Config Flags1; + typedef Flags Flags2; + DISPLAY (Flags1); + DISPLAY (Flags2); + // should denote the same type + Flags1::Flags flags1 = Flags2::Tuple(); + Flags2::Tuple flags2 = flags1; + ASSERT (1==sizeof(flags1)); // pure marker-type without content + ASSERT (1==sizeof(flags2)); + + typedef DefineConfigByFlags,NullType> >::Config SimpleConfig_defined_by_Typelist; + DISPLAY (SimpleConfig_defined_by_Typelist); + + typedef DefineConfigByFlags::Config AnotherConfig_defined_by_Typelist; + DISPLAY (AnotherConfig_defined_by_Typelist); + } + + + /** @test creates a predicate template (metafunction) returning true + * iff the template \c Maybe is defined for the configuration in question + */ + void check_instantiation () + { + #define CAN_INSTANTIATE(NAME) \ + cout << "defined " \ + << STRINGIFY(NAME) \ + << "? ---> " \ + << Instantiation::Test::value << "\n"; + + PRINT_DELIMITER (check_instantiation()); + + CAN_INSTANTIATE (Conf0); + CAN_INSTANTIATE (Conf1); + CAN_INSTANTIATE (Conf2); + CAN_INSTANTIATE (Conf3); + CAN_INSTANTIATE (Conf4); + + typedef Config Trash; + CAN_INSTANTIATE (Trash); + } + + + /** @test given a list of flag-tuples, we first create config-types out of them + * and then filter out those configs for which \c template Maybe is defined + */ + void check_filter () + { + PRINT_DELIMITER (check_filter()); + + DISPLAY (SomeFlagsets); + + typedef Apply Configs_defined_by_Flagsets; + DISPLAY (Configs_defined_by_Flagsets); + + typedef Filter::Test> Filter_possible_Configs; + DISPLAY (Filter_possible_Configs); + + + DISPLAY (AllFlagCombinations); + typedef Apply ListAllConfigs; + DISPLAY (ListAllConfigs); + + typedef Filter::Test> Filter_all_possible_Configs; + DISPLAY (Filter_all_possible_Configs); + } + + + + struct TestVisitor + { + string result; + TestVisitor() : result ("TestVisitor application:\n") {} + + /* === visitation interface === */ + typedef string Ret; + + Ret done() {return result; } + + template + void + visit (ulong code) + { + result += str (format ("visit(code=%u) -->%s\n") + % code % Printer::print() ); + } + }; + + /** @test FlagInfo metafunction, which takes as argument a list-of-flags + * as well as a list-of-lists-of-flags and especially allows to + * apply a visitor object to the latter + */ + void check_FlagInfo() + { + PRINT_DELIMITER (check_FlagInfo()); + + DISPLAY (Flags1); + cout << "max bit : " << FlagInfo::BITS <<"\n"; + cout << "binary code: " << FlagInfo::CODE <<"\n"; + + typedef Apply SomeConfigs; + DISPLAY (SomeConfigs); + cout << "max bit in [SomeConfigs] : " << FlagInfo::BITS <<"\n"; + + TestVisitor visitor; + cout << FlagInfo::accept (visitor); + } + + + template + struct TestFactory + { + uint operator() () { return offset_ + Maybe::CODE; } + TestFactory(long o) : offset_(o) {} + + private: + long offset_; + }; + + + /** @test use the ConfigSelector template to build a set of factories, + * based on a set of configurations. Then invoke the apropriate + * factory by specifying the configuration bit code + */ + void check_ConfigSelector() + { + PRINT_DELIMITER (check_ConfigSelector()); + + typedef Apply ListAllConfigs; + typedef Filter::Test> Possible_Configs; + DISPLAY (Possible_Configs); + + typedef engine::config::ConfigSelector< TestFactory // Factory template + , uint(void) // Factory function type + , long // common ctor argument + > TestFactorySelector; + + const long offset = 1000; // parameter fed to all TestFactory ctors + TestFactorySelector testConfigSelector (Possible_Configs::List(), offset); + + + #define INVOKE_CONFIG_SELECTOR(CODE) \ + cout << " Flag-code = " << CODE \ + << " ConfigSelector() ---> " \ + << testConfigSelector[CODE] () << "\n"; + + INVOKE_CONFIG_SELECTOR (2); + INVOKE_CONFIG_SELECTOR (12); + INVOKE_CONFIG_SELECTOR (20); + INVOKE_CONFIG_SELECTOR (4); + INVOKE_CONFIG_SELECTOR (8); + + try + { + INVOKE_CONFIG_SELECTOR (23); + NOTREACHED ; + } + catch (lumiera::error::Invalid& err) + { + cout << err.what() << "\n"; + lumiera_error (); // reset errorflag + } + } + + + }; + + + /** Register this test class... */ + LAUNCHER (ConfigFlags_test, "unit common"); + + + + } // namespace test + + } // namespace typelist + +} // namespace lumiera diff --git a/tests/common/typelistutiltest.cpp b/tests/common/meta/generatortest.cpp similarity index 94% rename from tests/common/typelistutiltest.cpp rename to tests/common/meta/generatortest.cpp index 73cab939e..2909b076d 100644 --- a/tests/common/typelistutiltest.cpp +++ b/tests/common/meta/generatortest.cpp @@ -1,5 +1,5 @@ /* - TypeListUtil(Test) - check the typelist helpers + Generator(Test) - build an interface + implementation directed by a typelis Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,7 +21,7 @@ * *****************************************************/ -/** @file typelistutiltest.cpp +/** @file generatortest.cpp ** \par what are we doing here?? ** ** the following test composes both an interface and the corresponding implementation @@ -31,14 +31,14 @@ ** need to be absolutely fixed in the class definition) ** ** @see typelisttest.cpp - ** @see typelistutil.hpp + ** @see generator.hpp ** @see lumiera::query::ConfigRules a real world usage example ** */ #include "common/test/run.hpp" -#include "common/typelistutil.hpp" +#include "common/meta/generator.hpp" #include #include @@ -118,7 +118,7 @@ namespace lumiera * for a collection of classes * */ - class TypeListUtil_test : public Test + class TypeListGenerator_test : public Test { virtual void run(Arg arg) { @@ -144,7 +144,7 @@ namespace lumiera /** Register this test class... */ - LAUNCHER (TypeListUtil_test, "unit common"); + LAUNCHER (TypeListGenerator_test, "unit common"); diff --git a/tests/common/meta/typelistdiagnostics.hpp b/tests/common/meta/typelistdiagnostics.hpp new file mode 100644 index 000000000..8de0e8d76 --- /dev/null +++ b/tests/common/meta/typelistdiagnostics.hpp @@ -0,0 +1,170 @@ +/* + TYPELISTDIAGNOSTICS - helper for testing the typelist based utilities + + 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. + +* *****************************************************/ + + +/** @file typelistdiagnostics.hpp + ** a Printer template usable for debugging the structure of a typelist built + ** upon some simple debugging-style types. Examples being a Num template, + ** or the Flag type. A Printer type generated from this template provides + ** a static \c print() function returing a string visualizing the structure + ** of the typelist provided as parameter to the Printer template. + ** + ** @see typelistmaniptest.cpp + ** @see configflagstest.cpp + ** + */ +#ifndef META_TYPELISTDIAGNOSTICS_H +#define META_TYPELISTDIAGNOSTICS_H + + +#include "common/meta/generator.hpp" + +//#include "common/meta/typelistutil.hpp" +//#include "common/meta/util.hpp" +//#include "common/util.hpp" + +#include + +using std::string; +using boost::format; + + +namespace lumiera { + namespace typelist { + + /** constant-wrapper type for debugging purposes, + * usable for generating lists of distinguishable types + */ + template + struct Num + { + enum{ VAL=I }; + }; + + + /* some forwards used by configflagstest.cpp */ + template struct Flag; + template< char f1 + , char f2 + , char f3 + , char f4 + , char f5 + > + struct Config; + + + + namespace test { + namespace { // internal definitions + + using boost::format; + + format fmt ("-<%u>%s"); + + struct NullP + { + static string print () { return "-"; } + }; + + /** debugging template, + * printing the "number" used for intantiation on ctor call + */ + template + struct Printer; + + template + struct Printer + : BASE + { + static string print () { return str( fmt % "·" % BASE::print()); } + }; + + template + struct Printer, BASE> ///< display the presence of a Num instance in the typelist + : BASE + { + static string print () { return str( fmt % uint(Num::VAL) % BASE::print()); } + }; + + template + struct Printer, BASE> ///< display the presence of a Flag in the typelist + : BASE + { + static string print () { return str( fmt % uint(Fl) % BASE::print()); } + }; + + + + /** call the debug-print for a typelist + * utilizing the Printer template */ + template + string + printSublist () + { + typedef InstantiateChained SubList; + return SubList::print(); + } + + /** Spezialisation for debug-printing of a nested sublist */ + template + struct Printer, BASE> + : BASE + { + static string print () + { + typedef Node List; + return string("\n\t+--") + printSublist()+"+" + + BASE::print(); + } + }; + + template + struct Printer, BASE> + : BASE + { + static string print () + { + typedef typename Config::Flags FlagList; + return string("\n\t+-Conf-[") + printSublist()+"]" + + BASE::print(); + } + }; + + +#define DIAGNOSE(LIST) \ + typedef InstantiateChained Contents_##LIST; + +#define DISPLAY(NAME) \ + DIAGNOSE(NAME); cout << STRINGIFY(NAME) << "\t:" << Contents_##NAME::print() << "\n"; + + + + } // (End) internal defs + + + + } // namespace test + + } // namespace typelist + +} // namespace lumiera +#endif diff --git a/tests/common/meta/typelistmaniptest.cpp b/tests/common/meta/typelistmaniptest.cpp new file mode 100644 index 000000000..f2b86c11e --- /dev/null +++ b/tests/common/meta/typelistmaniptest.cpp @@ -0,0 +1,241 @@ +/* + TypeListManip(Test) - appending, mixing and filtering typelists + + 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. + +* *****************************************************/ + + +/** @file typelistmaniptest.cpp + ** \par checking the correct working of simple list manipulation metafunctions + ** + ** The semi-automatic assembly of processing node invocation code utilizes some + ** metaprogramming magic built upon simple list manipulation. As template metaprogramming + ** is kind-of functional programming, most of this is done by recursion. + ** To check the correct working, this test uses some constant-wrapper types and a debugging + ** template which will print these constant numbers, thus allowing to verify in the output + ** if various lists of such constant-wrapper types were manipulated as expected. + ** + ** @see typelisttest.cpp + ** @see typelistutil.hpp + ** @see nodewiringconfig.hpp real world usage example + ** + */ + + +#include "common/test/run.hpp" +#include "common/meta/generator.hpp" +#include "common/meta/typelistutil.hpp" +#include "meta/typelistdiagnostics.hpp" +#include "common/util.hpp" + +#include +#include + +using ::test::Test; +using std::string; +using std::cout; + + +namespace lumiera { + namespace typelist { + namespace test { + + + namespace { // test data + + + + typedef Types< Num<1> + , Num<2> + , Num<3> + >::List List1; + typedef Types< Num<5> + , Num<6> + , Num<7> + >::List List2; + + + template struct CountDown { typedef NullType List; }; + template<> struct CountDown > { typedef Node, NullType> List; }; + template struct CountDown > { typedef Node, typename CountDown >::List> List; }; + + + + } // (End) test data + + + + + + + /************************************************************************* + * @test check utilities for manipulating lists-of-types. + * - build an list of constant-wrapper-types and + * print them for debugging purpose. + * - append lists, single elements and NullType + * in various combinations + * - filtering out some types from a typelist by + * using a "predicate template" (metafuction) + * - building combinations and permutations + */ + class TypeListManipl_test : public Test + { + virtual void run(Arg arg) + { + check_diagnostics (); + check_apply (); + check_append (); + check_filter (); + check_prefix (); + check_distribute(); + check_combine(); + } + + + void check_diagnostics () + { + // Explanation: the DISPLAY macro expands as follows.... + typedef InstantiateChained Contents_List1; + cout << "List1" << "\t:" << Contents_List1::print() << "\n"; + + // That is: we instantiate the "Printer" template for each of the types in List1, + // forming an inheritance chain. I.e. the defined Type "Contents_List1" inherits + // from each instantiation (single inheritance). + // The print() function is defined to create a string showing each. + + DISPLAY (List2); + } + + + void check_append () + { + typedef Append Append1; + DISPLAY (Append1); + + typedef Append,Num<22> > Append2; + DISPLAY (Append2); + + typedef Append,NullType> Append3; + DISPLAY (Append3); + + typedef Append > Append4; + DISPLAY (Append4); + + typedef Append Append5; + DISPLAY (Append5); + + typedef Append Append6; + DISPLAY (Append6); + + typedef Append,List2> Append7; + DISPLAY (Append7); + + typedef Append > Append8; + DISPLAY (Append8); + + typedef Append Append9; + DISPLAY (Append9); + } + + template struct AddConst2 { typedef X Type; }; + template struct AddConst2 > { typedef Num Type; }; + + void check_apply () + { + typedef Apply Added2; + DISPLAY (Added2); + } + + + template struct IsEven { enum {value = false }; }; + template struct IsEven > { enum {value = (0 == I % 2) }; }; + + void check_filter () + { + typedef Filter::List, IsEven > FilterEven; + DISPLAY (FilterEven); + } + + + void check_prefix () + { + typedef PrefixAll,Num<22> > Prefix1; + DISPLAY (Prefix1); + + typedef PrefixAll,List1> Prefix2; + DISPLAY (Prefix2); + + typedef PrefixAll Prefix3; + DISPLAY (Prefix3); + + typedef Types,List2::List>::List List_of_Lists; + typedef PrefixAll,List_of_Lists> Prefix4; + DISPLAY (Prefix4); + + typedef PrefixAll Prefix5; + DISPLAY (Prefix5); + + typedef PrefixAll Prefix6; + DISPLAY (Prefix6); + } + + + void check_distribute() + { + typedef Distribute, List1> Dist1; + DISPLAY (Dist1); + + typedef Types,Num<22>,Num<33> >::List Prefixes; + typedef Distribute > Dist2; + DISPLAY (Dist2); + + typedef Distribute Dist3; + DISPLAY (Dist3); + + typedef Distribute::List> Dist4; + DISPLAY (Dist4); + } + + + void check_combine() + { + typedef CountDown > Down; + DISPLAY (Down); + + typedef Combine Combi; + DISPLAY (Combi); + + typedef CombineFlags OnOff; + DISPLAY (OnOff); + } + + + }; + + + /** Register this test class... */ + LAUNCHER (TypeListManipl_test, "unit common"); + + + + } // namespace test + + } // namespace typelist + +} // namespace lumiera diff --git a/tests/common/typelisttest.cpp b/tests/common/meta/typelisttest.cpp similarity index 98% rename from tests/common/typelisttest.cpp rename to tests/common/meta/typelisttest.cpp index 42159d96c..5c942b1e0 100644 --- a/tests/common/typelisttest.cpp +++ b/tests/common/meta/typelisttest.cpp @@ -22,7 +22,7 @@ #include "common/test/run.hpp" -#include "common/typelist.hpp" +#include "common/meta/typelist.hpp" #include diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am index 088dbe668..3fce30365 100644 --- a/tests/components/Makefile.am +++ b/tests/components/Makefile.am @@ -47,7 +47,8 @@ test_components_SOURCES = \ $(testcomponents_srcdir)/proc/asset/makecliptest.cpp \ $(testcomponents_srcdir)/proc/asset/orderingofassetstest.cpp \ $(testcomponents_srcdir)/proc/asset/testasset.cpp \ - $(testcomponents_srcdir)/proc/engine/sourcenodetest.cpp \ + $(testcomponents_srcdir)/proc/engine/bufftabletest.cpp \ + $(testcomponents_srcdir)/proc/engine/sourcenodetest.cpp \ $(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \ $(testcomponents_srcdir)/proc/mobject/builder/buildsegmenttest.cpp \ $(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \ diff --git a/tests/components/proc/engine/bufftabletest.cpp b/tests/components/proc/engine/bufftabletest.cpp new file mode 100644 index 000000000..420d30636 --- /dev/null +++ b/tests/components/proc/engine/bufftabletest.cpp @@ -0,0 +1,180 @@ +/* + BuffTable(Test) - check consistency of buffer table chunk allocation + + 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 "common/test/run.hpp" +#include "common/error.hpp" + +#include "proc/engine/procnode.hpp" +#include "proc/engine/bufftable.hpp" + +#include +#include +#include +#include + +using test::Test; +using std::cout; +using std::rand; + + +namespace engine { + namespace test { + + namespace { // used internally + + const uint TABLE_SIZ = 100000; + const uint CHUNK_MAX = 8000; + const uint WIDTH_MAX = 3; + + + /** just some crap to pass in as ctor argument... */ + template + struct DummyArray : RefArray + { + E decoy; + E const& operator[] (uint i) const { return decoy;} + }; + DummyArray dummy1; + DummyArray dummy2; + + + /** a "hijacked" WiringDescriptor requesting + * a random number of inputs and outputs */ + struct MockSizeRequest + : WiringDescriptor + { + uint ii,oo; + + MockSizeRequest() + : WiringDescriptor(dummy1,dummy2,0), + ii(rand() % CHUNK_MAX), + oo(rand() % CHUNK_MAX) + { } + + virtual uint getNrI() const { return ii; } + virtual uint getNrO() const { return oo; } + + virtual BuffHandle callDown (State&, uint) const + { throw lumiera::Error("not intended to be called"); } + }; + + + + void* + detect_start_level (BuffTableStorage& sto) + { + return BuffTableChunk(MockSizeRequest(), sto ).outHandle; + } // address of first available storage element + + + inline void* + first_behind (BuffTable const& thisChunk, const uint nrI) + { + return &thisChunk.inHandle[nrI]; + } + + + inline bool + not_within(void* candidate, void* lower, void* upper) + { + return (candidate < lower) || (upper <= candidate); + } + + + bool + consistencyCheck (BuffTable const& b, WiringDescriptor const& num, void* lastLevel) + { + return (b.outHandle == lastLevel ) // storage is allocated continously + && (b.outBuff <= b.inBuff ) // input slots are behind the output slots + && (b.outHandle <= b.inHandle) + && (b.inBuff == &b.outBuff [num.getNrO()]) + && (b.inHandle == &b.outHandle[num.getNrO()]) + && (not_within(b.outBuff, b.outHandle, &b.inHandle[num.getNrO()])) // storage doesn't overlap + && (not_within(b.inBuff, b.outHandle, &b.inHandle[num.getNrO()])) + && (not_within(b.outHandle, b.outBuff, &b.inBuff[num.getNrO()])) + && (not_within(b.inHandle, b.outBuff, &b.inBuff[num.getNrO()])) + ; + } + } // (End) internal defs + + + + /******************************************************************* + * @test create a random pattern of recursive invocations, each + * allocating a chunk out of a global buffer table storage. + * After returning, each allocation should be cleanly + * deallocated and the internal level in the storage vector + * should have dopped to zero again. + */ + class BuffTable_test : public Test + { + typedef boost::scoped_ptr PSto; + + PSto pStorage; + ulong counter; + + virtual void run(Arg arg) + { + counter = 0; + std::srand (time (NULL)); + + // allocate storage block to be used chunk wise + pStorage.reset (new BuffTableStorage (TABLE_SIZ)); + + invocation (0, detect_start_level(*pStorage)); + + pStorage.reset(0); // dtor throws assertion error if corrupted + + cout << "BuffTable chunks allocated: "< reg_; - typedef P > O; - typedef P > P; + typedef lumiera::P > O; + typedef lumiera::P > P; typedef Query > Q13; typedef Query > Q23; diff --git a/uml/lumiera/128389 b/uml/lumiera/128389 index 2a8c1a7c0..05bf51f89 100644 --- a/uml/lumiera/128389 +++ b/uml/lumiera/128389 @@ -1,6 +1,6 @@ format 40 "RenderEngine" // ProcessingLayer::RenderEngine - revision 16 + revision 17 modified_by 5 "hiv" // class settings //class diagram settings @@ -517,11 +517,6 @@ ${inlines} class 142469 "StateProxy" visibility package stereotype "implementation" - nformals 2 - formal name "WIRING" type "class" explicit_default_value "" - explicit_extends "" - formal name "POLICY" type "class" explicit_default_value "" - explicit_extends "" cpp_decl "${comment}${template}class ${name}${inherit} { ${members} }; @@ -539,22 +534,6 @@ ${inlines} b multiplicity "" parent class_ref 132741 // State end - classrelation 153221 // - relation 149765 ---|> - a public - cpp default "${type}" - classrelation_ref 153221 // - b multiplicity "" parent class_ref 143877 // InPlace - end - - classrelation 154117 // wiring () - relation 150661 ---> - a role_name "wiring" multiplicity "1" const_relation protected - cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; -" - classrelation_ref 154117 // wiring () - b multiplicity "" parent class_ref 144005 // WiringTable - end end class 142597 "StateAdapter" @@ -621,12 +600,30 @@ ${inlines} idl_decl "" explicit_switch_type "" + operation 136453 "callDown" + cpp_virtual public explicit_return_type "" + nparams 2 + param inout name "" type class_ref 132741 // State + param in name "requiredOutput" explicit_type "uint" + nexceptions 1 + exception class_ref 144133 // BuffHandle + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end end class 143365 "NodeWiring" visibility package nformals 1 - formal name "STATE" type "class" explicit_default_value "" + formal name "CONF" type "class" explicit_default_value "" explicit_extends "" cpp_decl "${comment}${template}class ${name}${inherit} { @@ -648,13 +645,74 @@ ${inlines} classrelation 153093 // relation 149637 -_-> a default - cpp default "Generated" + cpp default "#include in header" classrelation_ref 153093 // b multiplicity "" parent class_ref 142597 // StateAdapter end + + classrelation 156165 // + relation 152581 ---- + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156165 // + b role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156293 // + end + + classrelation 156421 // + relation 152709 ---- + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156421 // + b role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156549 // + end + + classrelation 156677 // + relation 152837 ---- + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156677 // + b role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156805 // + end + + classrelation 156933 // + relation 152965 ---> + stereotype "creates" + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156933 // + b multiplicity "" parent class_ref 144261 // Invocation + end + + operation 136581 "callDown" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end end - class 143493 "InvocationStateBase" + class 143493 "OperationBase" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -665,16 +723,9 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 153733 // - relation 150277 ---|> - a public - cpp default "${type}" - classrelation_ref 153733 // - b multiplicity "" parent class_ref 132741 // State - end end - class 143621 "Caching" + class 143621 "QueryCache" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -685,16 +736,16 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 153605 // - relation 150149 ---|> + classrelation 157189 // + relation 153221 ---|> a public cpp default "${type}" - classrelation_ref 153605 // - b multiplicity "" parent class_ref 143493 // InvocationStateBase + classrelation_ref 157189 // + b multiplicity "" parent class_ref 143749 // PullInput end end - class 143749 "Process" + class 143749 "PullInput" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -705,16 +756,28 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 153477 // - relation 150021 ---|> + classrelation 157317 // + relation 153349 ---|> a public cpp default "${type}" - classrelation_ref 153477 // - b multiplicity "" parent class_ref 143621 // Caching + classrelation_ref 157317 // + b multiplicity "" parent class_ref 144389 // ProcessData + end + + classrelation 158085 // + relation 154117 ---- + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 158085 // + b role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 158213 // end end - class 143877 "InPlace" + class 143877 "ReadSource" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -725,16 +788,119 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 153349 // - relation 149893 ---|> + classrelation 157701 // + relation 153733 ---|> a public cpp default "${type}" - classrelation_ref 153349 // - b multiplicity "" parent class_ref 143749 // Process + classrelation_ref 157701 // + b multiplicity "" parent class_ref 143493 // OperationBase end end - class 144005 "WiringTable" + class 144389 "ProcessData" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 157445 // + relation 153477 ---|> + a public + cpp default "${type}" + classrelation_ref 157445 // + b multiplicity "" parent class_ref 144645 // FeedCache + end + + classrelation 157829 // + relation 153861 ---|> + a public + cpp default "${type}" + classrelation_ref 157829 // + b multiplicity "" parent class_ref 143493 // OperationBase + end + + classrelation 158213 // + relation_ref 154117 // + end + end + + class 144645 "FeedCache" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 157573 // + relation 153605 ---|> + a public + cpp default "${type}" + classrelation_ref 157573 // + b multiplicity "" parent class_ref 143493 // OperationBase + end + end + + class 144517 "Strategy" + visibility package + nformals 1 + formal name "CONF" type "class" explicit_default_value "" + explicit_extends "" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 154757 // + relation 151301 ---|> + a public + cpp default "${type}" + classrelation_ref 154757 // + b multiplicity "" parent class_ref 143877 // ReadSource + end + + classrelation 156293 // + relation_ref 152581 // + end + + classrelation 156549 // + relation_ref 152709 // + end + + classrelation 156805 // + relation_ref 152837 // + end + + classrelation 157061 // + relation 153093 ---|> + a public + cpp default "${type}" + classrelation_ref 157061 // + b multiplicity "" parent class_ref 143621 // QueryCache + end + + classrelation 157957 // + relation 153989 ---|> + a public + cpp default "${type}" + classrelation_ref 157957 // + b multiplicity "" parent class_ref 143749 // PullInput + end + end + + class 144005 "BuffTable" visibility package nformals 1 formal name "SIZ" type "int" explicit_default_value "" @@ -780,5 +946,44 @@ ${inlines} explicit_switch_type "" end + + class 144261 "Invocation" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 155781 // + relation 152197 ---> + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 155781 // + b multiplicity "" parent class_ref 142597 // StateAdapter + end + + classrelation 155909 // + relation 152325 ---> + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 155909 // + b multiplicity "" parent class_ref 142725 // WiringDescriptor + end + + classrelation 156037 // + relation 152453 ---> + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 156037 // + b multiplicity "" parent class_ref 144005 // BuffTable + end + end end end diff --git a/uml/lumiera/128901 b/uml/lumiera/128901 index 455fee7d7..9a2bf5b90 100644 --- a/uml/lumiera/128901 +++ b/uml/lumiera/128901 @@ -1,6 +1,6 @@ format 40 "Builder" // ProcessingLayer::MObject::Builder - revision 16 + revision 17 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 246c9e4d6..1441c4bdf 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 21 + revision 22 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram index 4b7003a43..dda416518 100644 --- a/uml/lumiera/131973.diagram +++ b/uml/lumiera/131973.diagram @@ -14,7 +14,7 @@ classcanvas 129669 class_ref 133253 // Frame end classcanvas 131845 class_ref 142469 // StateProxy draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 126 211 2000 + xyz 126 220 2000 end classcanvas 131973 class_ref 142597 // StateAdapter draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default @@ -22,11 +22,13 @@ classcanvas 131973 class_ref 142597 // StateAdapter end classcanvas 132357 class_ref 142725 // WiringDescriptor draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 229 497 2000 + hidden_operations + operation_ref 136453 // callDown + xyz 229 498 2000 end classcanvas 135045 class_ref 143365 // NodeWiring draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 241 568 2000 + xyz 241 561 2000 end textcanvas 135685 "determines concrete Type" xyzwh 100 594 2004 130 18 @@ -37,15 +39,15 @@ relationcanvas 129797 relation_ref 134533 // no_multiplicity_a multiplicity_b_pos 173 109 3000 relationcanvas 132101 relation_ref 148869 // geometry VHV unfixed - from ref 131973 z 1999 to point 78 181 - line 134021 z 1999 to point 118 181 + from ref 131973 z 1999 to point 78 186 + line 134021 z 1999 to point 118 186 line 134149 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 132229 relation_ref 148997 // geometry VHV - from ref 131845 z 1999 to point 178 181 - line 134277 z 1999 to point 118 181 + from ref 131845 z 1999 to point 178 186 + line 134277 z 1999 to point 118 186 line 134405 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b @@ -53,13 +55,13 @@ relationcanvas 132485 relation_ref 149125 // geometry HV from ref 128005 z 1999 stereotype "<>" xyz 205 454 3000 to point 277 452 line 133381 z 1999 to ref 132357 - role_a_pos 289 472 3000 no_role_b - multiplicity_a_pos 265 472 3000 no_multiplicity_b + role_a_pos 289 473 3000 no_role_b + multiplicity_a_pos 265 473 3000 no_multiplicity_b relationcanvas 133509 relation_ref 149253 // from ref 131973 z 1999 to point 178 312 line 133637 z 1999 to ref 131845 - role_a_pos 190 302 3000 no_role_b - multiplicity_a_pos 164 302 3000 no_multiplicity_b + role_a_pos 190 293 3000 no_role_b + multiplicity_a_pos 164 293 3000 no_multiplicity_b relationcanvas 134533 relation_ref 149381 // from ref 131973 z 3004 to ref 129669 no_role_a no_role_b diff --git a/uml/lumiera/132357.diagram b/uml/lumiera/132357.diagram index a097c7137..5a7ffa76a 100644 --- a/uml/lumiera/132357.diagram +++ b/uml/lumiera/132357.diagram @@ -1,81 +1,172 @@ format 40 -classcanvas 128005 class_ref 132741 // State +classcanvas 128133 class_ref 143493 // OperationBase draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 78 10 2000 + xyz 232 13 2000 end -classcanvas 128133 class_ref 143493 // InvocationStateBase +classcanvas 128261 class_ref 143621 // QueryCache draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 203 104 2000 + xyz 186 252 2000 end -classcanvas 128261 class_ref 143621 // Caching +classcanvas 128517 class_ref 143877 // ReadSource draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 235 157 2000 + xyz 297 165 2000 end -classcanvas 128389 class_ref 143749 // Process +classcanvas 130309 class_ref 144005 // BuffTable draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 236 212 2000 - end -classcanvas 128517 class_ref 143877 // InPlace - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 238 268 2000 - end -classcanvas 128645 class_ref 142469 // StateProxy - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 209 332 2004 - end -classcanvas 130309 class_ref 144005 // WiringTable - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 101 298 2000 + xyz 100 508 2000 end classcanvas 130437 class_ref 142725 // WiringDescriptor draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 36 213 2005 + xyz 82 319 2005 end classcanvas 130565 class_ref 144133 // BuffHandle draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 36 379 2000 + xyz 169 563 2000 end textcanvas 131461 "const" - xyzwh 109 257 2010 29 18 -relationcanvas 128901 relation_ref 149765 // - from ref 128645 z 1999 to ref 128517 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129029 relation_ref 149893 // - from ref 128517 z 1999 to ref 128389 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129157 relation_ref 150021 // - from ref 128389 z 1999 to ref 128261 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129285 relation_ref 150149 // - from ref 128261 z 1999 to ref 128133 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129413 relation_ref 150277 // - from ref 128133 z 1999 to point 260 69 - line 129925 z 1999 to point 190 69 - line 130181 z 1999 to point 161 176 - line 130053 z 1999 to point 118 176 - line 129797 z 1999 to ref 128005 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b + xyzwh 101 388 2010 29 18 +classcanvas 131717 class_ref 144261 // Invocation + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + color lightorange + xyz 31 439 2000 + end +classcanvas 131845 class_ref 143365 // NodeWiring + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 222 423 2005 + end +classcanvas 131973 class_ref 142597 // StateAdapter + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 25 230 2005 + end +classcanvas 132357 class_ref 144389 // ProcessData + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 186 140 2015 + end +classcanvas 132997 class_ref 144517 // Strategy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 199 319 3010 + end +classcanvas 133253 class_ref 144517 // Strategy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 301 301 2005 + end +classcanvas 134021 class_ref 144645 // FeedCache + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 190 80 2010 + end +classcanvas 134533 class_ref 144389 // ProcessData + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 238 125 2004 + end +classcanvas 134661 class_ref 144517 // Strategy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 250 309 3005 + end +textcanvas 137477 "as configured" + xyzwh 308 376 3010 68 18 +classcanvas 137733 class_ref 143749 // PullInput + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 194 198 2010 + end +classcanvas 137861 class_ref 143749 // PullInput + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 247 184 2005 + end +textcanvas 139781 "Policy Classes" + xyzwh 163 50 2005 81 21 relationcanvas 130693 relation_ref 150405 // geometry VHr - from ref 130309 z 1999 stereotype "<>" xyz 43 309 3000 to point 70 326 + from ref 130309 z 1999 stereotype "<>" xyz 177 517 3000 to point 203 536 line 130821 z 1999 to ref 130565 no_role_a no_role_b - multiplicity_a_pos 45 354 3000 no_multiplicity_b + multiplicity_a_pos 211 537 3000 no_multiplicity_b relationcanvas 130949 relation_ref 150533 // from ref 130309 z 1999 to ref 130437 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 131077 relation_ref 150661 // - geometry VHr - from ref 128645 z 1999 to point 136 371 - line 131333 z 1999 to ref 130309 - role_a_pos 148 367 3000 no_role_b - multiplicity_a_pos 122 359 3000 no_multiplicity_b +relationcanvas 132229 relation_ref 149509 // + from ref 131845 z 2004 to point 219 401 + line 137605 z 2004 to point 162 401 + line 137221 z 2004 to ref 130437 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 133381 relation_ref 151301 // + from ref 133253 z 1999 to point 333 274 + line 137349 z 1999 to ref 128517 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 135685 relation_ref 152197 // + from ref 131717 z 1999 to ref 131973 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 135813 relation_ref 152325 // + from ref 131717 z 1999 to ref 130437 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 135941 relation_ref 152453 // + geometry VH + from ref 131717 z 1999 to point 63 536 + line 137093 z 1999 to ref 130309 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 136069 relation_ref 152581 // + from ref 131845 z 2004 to ref 132997 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 136197 relation_ref 152709 // + from ref 131845 z 2004 to ref 134661 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 136325 relation_ref 152837 // + from ref 131845 z 2004 to ref 133253 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 136453 relation_ref 152965 // + from ref 131845 z 1999 stereotype "<>" xyz 145 441 3000 to ref 131717 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 137989 relation_ref 153093 // + from ref 132997 z 1999 to point 222 316 + line 139653 z 1999 to ref 128261 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138117 relation_ref 153221 // + from ref 128261 z 1999 to ref 137733 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138245 relation_ref 153349 // + from ref 137733 z 2009 to ref 132357 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138373 relation_ref 153477 // + from ref 132357 z 2009 to ref 134021 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138501 relation_ref 153605 // + geometry VHV unfixed + from ref 134021 z 1999 to point 223 68 + line 138885 z 1999 to point 275 68 + line 139013 z 1999 to ref 128133 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138629 relation_ref 153733 // + geometry VHV unfixed + from ref 128517 z 1999 to point 333 68 + line 139141 z 1999 to point 275 68 + line 139269 z 1999 to ref 128133 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138757 relation_ref 153861 // + from ref 134533 z 1999 to ref 128133 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 139397 relation_ref 153989 // + from ref 134661 z 2004 to ref 137861 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 139525 relation_ref 154117 // + from ref 137861 z 2003 to ref 134533 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b end diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index 1a789da17..3de151827 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -1,11 +1,11 @@ -window_sizes 1140 830 270 860 680 71 +window_sizes 1302 1004 270 1022 854 71 diagrams classdiagram_ref 131973 // Render Mechanics - 428 623 100 4 2 0 + 407 690 100 4 2 0 collaborationdiagram_ref 132229 // Render Process - 817 644 100 4 0 0 + 825 684 100 4 0 0 active classdiagram_ref 132357 // StateAdapter composition - 418 520 100 4 0 0 + 414 658 100 4 0 0 end show_stereotypes selected @@ -17,6 +17,16 @@ package_ref 129029 // Controller class_ref 131717 // ProcNode class_ref 142469 // StateProxy class_ref 142597 // StateAdapter + class_ref 142725 // WiringDescriptor + class_ref 143365 // NodeWiring + class_ref 143621 // QueryCache + class_ref 143749 // PullInput + class_ref 143877 // ReadSource + class_ref 144389 // ProcessData + class_ref 144645 // FeedCache + class_ref 144517 // Strategy + class_ref 144005 // BuffTable + class_ref 144261 // Invocation usecaseview_ref 128005 // Renderengine Use class_ref 140677 // QueryHandler class_ref 140805 // TypeHandler diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index 2238424c2..a533da6cc 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 47 + revision 48 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/compatibility.html b/wiki/compatibility.html index 0d6077a15..56353ac46 100644 --- a/wiki/compatibility.html +++ b/wiki/compatibility.html @@ -747,7 +747,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS } //}}} -
+
! Programming Languages
 * C
 ** a C99 compatible compiler, some GCC extensions are used, most are optional.
@@ -782,13 +782,15 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
 * boost (see above, version 1.35 works too)
 * NoBug
 * [[GAVL|http://gmerlin.sourceforge.net/gavl.html]] (1.0.0) 
-* for the GUI: gtkmm-2.4 gdl-1.0 cairomm-1.0 xv
+* for the GUI: gtkmm-2.4 gdl-1.0 libglibmm-2.4 cairomm-1.0 xv
 ** libgtkmm-2.4-dev (>=2.8)
 ** libcairomm-1.0-dev (>=0.6.0)
 ** libgdl-1-dev (>=0.6.1)
 *** libbonoboui2-dev (>=2.14.0)
+** libglibmm-2.4-dev (>=2.16), requiring glib2.0 (>=2.16)
 ** libxv-dev ~~(1.0.2 is known to work)~~
 
+
 //usually, newer versions are OK//
 
 
diff --git a/wiki/draw/LumiLogo.png b/wiki/draw/LumiLogo.png new file mode 100644 index 000000000..1fd263aed Binary files /dev/null and b/wiki/draw/LumiLogo.png differ diff --git a/wiki/draw/high-level1.png b/wiki/draw/high-level1.png new file mode 100644 index 000000000..439cd9e1a Binary files /dev/null and b/wiki/draw/high-level1.png differ diff --git a/wiki/draw/high-level2.png b/wiki/draw/high-level2.png new file mode 100644 index 000000000..33193c533 Binary files /dev/null and b/wiki/draw/high-level2.png differ diff --git a/wiki/draw/high-level3.png b/wiki/draw/high-level3.png new file mode 100644 index 000000000..dbfadc50f Binary files /dev/null and b/wiki/draw/high-level3.png differ diff --git a/wiki/index.html b/wiki/index.html index 75eedf40a..fd3fe210e 100644 --- a/wiki/index.html +++ b/wiki/index.html @@ -759,7 +759,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS } //}}}
-
+
for __Building__
 * gcc (4.1), glibc6 (2.3), libstdc++6 (4.1)
 * [[build system|BuildSystem]] dependencies: SCons (0.96.90), Python (2.4), pkg-config
@@ -773,11 +773,12 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
 ** libboost-program-options1.34.1 (>=1.34.1-2) ''NOTE: binary dependency''
 ** libboost-regex-dev (>=1.34.1-2)
 ** libboost-regex1.34.1 (>=1.34.1-2) ''binary..''
-* for the GUI: gtkmm-2.4 gdl-1.0 cairomm-1.0 xv
+* for the GUI: gtkmm-2.4 gdl-1.0 libglibmm-2.4 cairomm-1.0 xv
 ** libgtkmm-2.4-dev (>=2.8)
 ** libcairomm-1.0-dev (>=0.6.0)
 ** libgdl-1-dev (>=0.6.1)
 *** libbonoboui2-dev (>=2.14.0)
+** libglibmm-2.4-dev (>=2.16), requiring glib2.0 (>=2.16)
 ** libxv-dev (>=1.0.2)
 //usually, newer versions are OK//
 
@@ -961,7 +962,7 @@ lumiera/mob is an anonymous account at pipapo.org where everyone can commit chan
 * [[1.official developer meeting 1.Feb.2008|IRC_2008-02-01]]
 * [[informal developer meeting 10.Aug.2007|IRC_2007-08-10]]
 
-!talks about distinct topics
+!talks about specific topics
 * [[buffer allocation for render nodes (6/08)|IRC_log_BufferAllocation_2008-06]]
 
@@ -2149,16 +2150,16 @@ This distributed wiki might be used instead the pipapo.org wiki, investigate tha Wiki works. It is simple to use and just flexible enough to handle the task. I don't go to install any other software for such tasks on my server. While the design progresses I'd propose to move our work into git repositories and eventually phase this wiki pages out anyways. I'd rather like to start out distributed/git right away .. but git gives us only a fine storage layer, for a design process we need some good presentation layer (later when using git and starting the implementation everyones favorite editor serves for that) I have no better ideas yet to solve the presentation problem other than using this wiki (or maybe Bouml).
-
-
This is the entry point to several [[TiddlyWiki]]-Pages containing the developer and design documentation for Lumiera.
+
+
[<img[draw/LumiLogo.png]]
 
-* Cehteh started GitNotes where we will collect some information about git, howto and special setups
-* since we prefer gpg signed tags in git and not each developer knows gpg well here is a Micro-GPG-HowTo 
+
+  ''Lumiera'' is the emerging professional non linear video editor for Linux
+
+This is the entry point to several [[TiddlyWiki]]-Pages containing the developer and design documentation.
 * we maintain (semi-) final design docs in DesignDocumentation
 * Things get often worked out on IRC, see IRC-Transcripts for decisions made there and not yet put into the proper documentation places
 
-Please __end your tiddlers in a newline__, this makes merging in git easier since the /pre tag used in tiddlywiki will become on a single line.
-
 ----
 !Architecture and Subsystems
 to get started, we create design drafts emphasizing different aspects and regions of Lumiera
diff --git a/wiki/renderengine.html b/wiki/renderengine.html
index 5dabc8bbb..64559e1e0 100644
--- a/wiki/renderengine.html
+++ b/wiki/renderengine.html
@@ -565,13 +565,24 @@ For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from
 
The Asset Manager provides an Interface to some internal Database holding all Assets in the current Session and System state. It may be a real Database at some point (and for the moment it's a Hashtable). Each [[Asset]] is registered automatically with the Asset Manager; it can be queried either by it's //identification tuple// or by it's unique ID.
-
-
Placing an MObject relatively to another object such that it should be handled as //attached&nbsp;// to the latter results in several implementation problems. The typical use case is that of an effect attached to a clip or processing pipe.
-* this attachment is not a globally fixed relation, rather, it typically exists only for some limited time span (e.g. the duration of the basic clip the effect is attached to)
+
+
Placing an MObject relatively to another object such that it should be handled as //attached//&nbsp; to the latter results in several design and implementation challenges. Actually, such an attachment creates a cluster of objects. The typical use case is that of an effect attached to a clip or processing pipe.
+* attachment is not a globally fixed relation between objects, rather, it typically exists only for some limited time span (e.g. the duration of the basic clip the effect is attached to)
 * the order of attachment is important and the attached placement may create a fork in the signal flow, so we need a way for specifying reproducibly how the resulting wiring should be
-* when building, we access the information in reversed direction: we have the target object and need to query for all attachements
+* when building, we access the information in reversed direction: we have the target object and need to query for all attachments
 
-The first step towards an solution is to isolate the problem; obviously we //need the information about attached objects // only for two isolated tasks, namely when building and for creating a GUI representation. So using a query (function call) interface, the rest of the problem is turned into an implementation detail.
+The first step towards an solution is to isolate the problem; obviously we don't need to store the objects differently, we just need //information about attached objects//&nbsp; for some quite isolated tasks (namely for creating a GUI representation and for combining attached objects into a [[Pipe]] when building). Resorting to a query (function call) interface should turn the rest of the problem into an implementation detail. Thus +* for an __attachment head__ (= {{{Placement<MObject>}}} to which other objects have been attached) get the ordered list of attachments +* for an __attached placement__ (member of the cluster) get the placement of the corresponding attachment head +* retrieve and break the attachment when //deleting.// + +!!Implementation notes +Attachment is managed within the participating placements, mostly by special [[locating pins|LocatingPin]]. Attachment doesn't necessarily nail down an attached object to a specific position, rather the behaviour depends on the type of the object and the locating pins actually involved, especially on their order and priority. For example, if an {{{Placement<Effect>}}} doesn't contain any locating pin defining a temporal position, then the attachment will result in the placement inheriting the temporal placement of the //attachment head// (i.e. the clip this effect has been attached to). But, if on the contrary the effect in question //does// have an additional locating pin, for example relative to another object or even to a fixed time position, this one will "win" and determine the start position of the effect &mdash; it may even move the effect out of the time interval covered by the clip, in which case the attachment has no effect on the clip's processing pipe. +The attachment relation is hierarchical and has a clearly defined //active// and //passive// side: The attachment head is the parent node in a tree, but plays the role of the passive partner, to which the child nodes attach. But note, this does not mean we are limited to a single attachment head. Actually, each placement has a list of locating pins and thus can attach to several other placements. For example, a transition attaches to at least two local pipes (clips). + +!!!!Relation to memory management +Attachment on itself does //not// keep an object alive. Rather, it's a direct reference and has to be taken into account when deleting an object. On the other hand, processing nodes in the render engine never depend on placements &mdsash; they always refer directly to the MObject instance or even the underlying asset. In the case of MObject instances, the pointer from within the engine will //share ownership// with the placement (remember: both are derived from {{{boost::shared_ptr}}}). +
Automation is treated as a function over time. It is always tied to a specific Parameter (which can thus be variable over the course of the timeline). All details //how// this function is defined are completely abstracted away. The Parameter uses a ParamProvider to get the value for a given Time (point). Typically, this will use linear or bezier interpolation over a set of keyframes internally. Parameters can be configured to have different value ranges and distribution types (on-off, stepped, continuous, bounded)
@@ -900,12 +911,12 @@ at the lowest level within the builder there is the step of building a //connect
 &rarr;see also: BuilderPrimitives for the elementary working situations corresponding to each of these [[builder moulds|BuilderMould]]
 
-
+
Background: #fefefd
 Foreground: #000
 PrimaryPale: #8fb
-PrimaryLight: #50d2ae
-PrimaryMid: #1b9989
+PrimaryLight: #4dc9a7
+PrimaryMid: #16877a
 PrimaryDark: #0f3f56
 SecondaryPale: #ffc
 SecondaryLight: #fe8
@@ -1082,7 +1093,7 @@ As always, the main goal is //to cut down complexity// by the usual approach to
 
 To achieve this, here we try to separate ''Configuration'' from ''Processing''. Further, in Configuration we try to separate the ''high level view'' (users view when editing) from the ''low level view'' (the actual configuration effective for the calculations). Finally, we try to factor out and encapsulate ''State'' in order to make State explicit.
 
-The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the [[automation data|Automation]], separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes are utilizing the same automation data).
+The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. All decisions, tests and conditional operations are factored out of the render process and handled as configuration of the pipeline, which is done by the Builder. The actual color model and number of ports is configured in by a pre-built wiring descriptor. All Nodes are of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. OpenGL and renderfarm support can be configured in as an alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering. We introduce separate control data connections for the [[automation data|Automation]], separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or the case of two nodes using the same automation data).
 
 Another pertinent theme is to make the basic building blocks simpler, while on the other hand gaining much more flexibility for combining these building blocks. For example we try to unfold any "internal-multi" effects into separate instances (e.g. the possibility of having an arbitrary number of single masks at any point of the pipeline instead of having one special masking facility encompassing multiple sub-masks. Similarly, we treat the Objects in the EDL in a more uniform manner and gain the possibility to [[place|Placement]] them in various ways.
 
@@ -1147,7 +1158,7 @@ The &raquo;Timeline&laquo; is a sequence of ~MObjects -- note: using the ---- After beeing processed by the Builder, we get a Render Engine configuration.<br> It has to be segmented at least at every point with changes in the configuration, but some variations are possible, e.g. we could create a Render Engine for every Frame (as Cinelerra2 does) or we could optimize out some configurations (for example the effect extended beyond the end of the clip) -{{red{note: as of 6/08 this can be taken only as the "big picture". Implementation will differ in details, and is more complicated than shown here}}} +{{red{note: as of 6/08 this can be taken only as the "big picture". Implementation will differ in details, and is more complicated than showed here}}} [img[Example2: generated Render Engine|uml/fig129157.png]]
@@ -1166,7 +1177,7 @@ To make the intended use of the classes more clear, consider the following two e
A special kind (subclass) of [[Placement]]. As such it is always linked to a //Subject//, i.e. a MObject. In addition to the properties of a (unspecific) Placement, the ExplicitPlacement specifies a absolute time and track position for locating the Subject
 
-
+
We use Factories
 * for centralizing [[memory management|MemoryManagement]]
 * to support polymorphism (of course...)
@@ -1186,37 +1197,36 @@ To make the intended use of the classes more clear, consider the following two e
 !!chosen design
 My main goal is to have an easy-to-use interface for the implementer of individual classes using this factory mechanism. The intended use should mimic the standard use of operator new, and at the same time there should be a possibility to configure »real« Factory behaviour in.
 
-For this reason I make Factory a Functor, and for handling the concrete memory allocation, it inherits from an Allocator class. The users of this factory template typically either parametrize it with existing smart-pointer types and some Allocator instantiation, or they may chose to create a specialized Factory derived from this Factory template. After typically hiding this configuration behind a typedef, the user adds a static field to the class intended to use the Factory and initializes this field with the concrete Factory (this may pass internal ~IDs to the constructor of the Factory and from there on to the underlying Allocator).
+For this reason I make Factory a Functor, so it can be incorporated as a member into another class, while still looking like a function call to the client code. The users of this factory template typically either parametrize it with existing smart-pointer types, or they may chose to create a specialized Factory derived from this Factory template. After typically hiding this configuration behind a typedef, the user adds a static field to the class intended to use the Factory and initializes this field with the concrete Factory (this may pass internal ~IDs to the constructor of the Factory and from there on to the underlying Allocator).
 {{{
 #include "common/factory.hpp"
 
-  class Blubb
+  class Product
     {
-      int uii ;
+      int wow_;
 
     public:
-      typedef lumiera::factory::RefcountPtr<Blubb> Factory;
+      typedef lumiera::factory::RefcountPtr<Product> Factory;
       static Factory create;
       
-      Blubb() : uii(42) {} ;
+      Product() : wow_(42) {} ;
     };
   
-  /** a static Factory instance 
-   *  for creating refcounting Ptrs to Blubb objects 
+  /** storage for a static Factory instance 
+   *  for creating refcounting Ptrs to Product objects 
    */
-  Blubb::Factory Blubb::create;  // <----note this is a constructor call
+  Product::Factory Product::create;  // <----note this is a ctor call
 }}}
-Now, the clients of {{{class Blubb}}} can create ref-counting pointers to Blubb-objects by doing a fully qualified {{{create()}}} functor call:
+Now, the clients of {{{class Product}}} can create ref-counting pointers to Product-objects by doing a fully qualified {{{create()}}} functor call:
 {{{
-  std::tr1::shared_ptr<Blubb> huii = Blubb::create ();  // <----will invoke the default Blubb() ctor 
-  std::tr1::shared_ptr<Blubb> pfuii = huii;
+  std::tr1::shared_ptr<Product> huii = Product::create ();  // <----will invoke the default Product() ctor 
+  std::tr1::shared_ptr<Product> pfuii = huii;
 }}}
 Some further details
-* Functor inherits (protected) from Allocator, besides that there are no additional requirements.
-* typically, Allocator provides a overloaded {{{operator new(size_t)}}} etc.
+* the product class (or base class) cares for using an custom allocator via an overloaded {{{operator new(size_t)}}} if applicable.
 * thus, when Functor or any derived class issues a new XX(), our custom Allocator gains control
 * the Functor-behaviour relies on a custom {{{operator()}}} which can be overridden in derived classes to take various parameter lists.
-* then, such a Factory class derived from Functor can do specific magic and e.g. create some subclass
+* additionally, such a Factory class derived from Functor can do specific magic and e.g. create some subclass
 * and, as the created smart-pointer is a template parameter, such a custom Functor can create all sorts of Proxies, wrappers and the like
 
@@ -1318,7 +1328,44 @@ For this Lumiera design, we could consider making GOP just another raw media dat &rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
-
+
+
While the low-level model holds the data used for carrying out the actual media data processing (=rendering), the high-level model is what the user works upon when performing edit operations through the GUI (or script driven in &raquo;headless mode&laquo;). Its building blocks and combination rules determine largely what structures can be created within the [[Session]].
+On the whole, it is a collection of [[media objects|MObjects]] stuck together and arranged by [[placements|Placement]].
+
+Basically, the structure of the high-level model is is a very open and flexible one &mdash; every valid connection of the underlying object types is allowed &mdash; but the transformation into a low-level node network for rendering follows certain patterns and only takes into account any objects reachable while processing the session data in accordance to these patterns. Taking into account the parameters and the structure of these objects visited when building, the low-level render node network is configured in detail.
+
+The fundamental metaphor or structural pattern is to create processing ''pipes'', which are a linear chain of data processing modules, starting from an source port and providing an exit point. [[Pipes|Pipe]] are a //concept or pattern,// they don't exist as objects. Each pipe has an input side and an output side and is in itself something like a Bus treating a single [[media stream|StreamType]] (but this stream may still have an internal structure, e.g. several channels related to a spatial audio system). Other processing entities like effects and transitions can be placed (attached) at the pipe, resulting them to be appended to form this chain. Optionally, there may be a ''wiring plug'', requesting the exit point to be connected to another pipe. When omitted, the wiring will be figured out automatically.
+Thus, when making an connection //to// a pipe, output data will be sent to the //source port// (input side) of the pipe, wheras when making a connection //from// a pipe, data from it's exit point will be routed to the destination. Incidentally, the low-level model and the render engine employ //pull-based processing,// but this is rather of no relevance for the high-level model.
+
+
+
+[img[draw/high-level1.png]]
+Normally, pipes are limited to a //strictly linear chain// of data processors ("''effects''") working on a single data stream type, and consequently there is a single ''exit point'' which may be wired to an destination. As an exception to this rule, you may insert wire tap nodes (probe points), which explicitly may send data to an arbitrary input port; they are never wired automatically. It is possible to create cyclic connections by such arbitrary wiring, which will be detected by the builder and flagged as an error.
+
+While pipes have a rather rigid and limited structure, it is allowed to make several connections to and from any pipe &mdash; even connections requiring an stream type conversion. It is not even necessary to specify //any// output destination, because then the wiring will be figured out automatically by searching the context and finally using some general rule. Connecting multiple outputs to the input of another pipe automatically creates a ''mixing step'' (which optionally can be controlled by a fader). Several pipes may be joined together by a ''transition'', which in the general case simultaneously treats N media streams. Of course, the most common case is to combine two streams into one output, thereby also mixing them. Most available transition plugins belong to this category, but, as said, the model isn't limited to this simple case, and moreover it is possible to attach several overlapping transitions covering the same time interval.
+
+Individual Media Objects are attached, located or joined together by ''Placements''. A [[Placement]] is a handle for a single MObject (implemented as a refcounting smart-ptr) and contains a list of placement specifications, called LocatingPin. Adding an placement to the session acts as if creating an //instance.// (it behaves like a clone in case of multiple placements of the same object). Besides absolute and relative placement, there is also the possibility of a placement to stick directly to another MObject's placement, e.g. for attaching an effect to a clip or to connect an automation data set to an effect. This //stick-to placement// creates sort of a loose clustering of objects: it will derive the position from the placement it is attached to. Note that while the length and the in/out points are a //property of the ~MObject,// it's actual location depends on how it is //placed// and thus can be maintained quite dynamically. Note further that effects can have an length on their own, thus by using these attachement mechaics, the wiring and configuration within the high-level model can be quite time dependant.
+
+[>img[draw/high-level2.png]]
+
+
+
+Actually a ''clip'' is handled as if it was comprised of local pipe(s). In the example shown here, a two-channel clip has three effects attached, plus a wiring plug. Each of those attachments is used only if applicable to the media stream type the respective pipe will process. As the clip has two channels (e.g. video and audio), it will have two ''source ports'' pulling from the underlying media. Thus, as showed in the drawing to the right, by chaining up any attached effect applicable to the respective stream type defined by the source port, effectively each channel (sub)clip gets its own specifically adapted processing pipe.
+
+@@clear(right):display(block):@@
+!!Example of an complete Session
+[img[draw/high-level3.png]]
+The Session contains several independent [[EDL]]s plus an output bus section (''global Pipes''). Each EDL holds a collection of ~MObjects placed within a ''tree of tracks''. 
+Within Lumiera, tracks are a rather passive means for organizing media objects, but aren't involved into the data processing themselves. The possibility of nesting tracks allows for easy grouping. Like the other objects, tracks are connected together by placements: A track holds the list of placements of its child tracks. Each EDL holds a single placement pointing to the root track. 
+
+As placements have the ability to cooperate and derive any missing placement specifications, this creates a hierarchical structure throughout the session, where parts on any level behave similar if applicable. For example, when a track is anchored to some external entity (label, sync point in sound, etc), all objects placed relatively to this track will adjust and follow automatically. This relation between the track tree and the individual objects is especially important for the wiring, which, if not defined locally within an ~MObject's placement, is derived by searching up this track tree and utilizing the wiring plug locating pins found there, if applicable. In the default configuration, the placement of an EDL's root track contains a wiring plug for video and another wiring plug for audio. This setup is sufficient for getting every object within this EDL wired up automatically to the correct global output pipe. Moreover, when adding another wiring plug to some sub track, we can intercept and reroute the connections of all objects creating output of this specific stream type within this track and on all child tracks.
+
+Besides routing to a global pipe, wiring plugs can also connect to the source port of an ''meta-clip''. In this example session, the outputs of ~EDL-2 as defined by locating pins in it's root track's placement, are directed to the source ports of a [[meta-cllip|VirtualClip]] placed within ~EDL-1. Thus, within ~EDL-1, the contents of ~EDL-2 appear like a pseudo-media, from which the (meta) clip has been taken. They can be adorned with effects and processed further completely similar to a real clip.
+
+Finally, this example shows an ''automation'' data set controlling some parameter of an effect contained in one of the global pipes. From the effect's POV, the automation is simply a ParamProvider, i.e a function yielding a scalar value over time. The automation data set may be implemented as a bézier curve, or by a mathematical function (e.g. sine or fractal pseudo random) or by some captured and interpolated data values. Interestingly, in this example the automation data set has been placed relatively to the meta clip (albeit on another track), thus it will follow and adjust when the latter is moved.
+
+
+
This wiki page is the entry point to detail notes covering some technical decisions, details and problems encountered in the course of the implementation of the Lumiera Renderengine, the Builder and the related parts.
 
 * [[Packages, Interfaces and Namespaces|InterfaceNamespaces]]
@@ -1336,6 +1383,7 @@ For this Lumiera design, we could consider making GOP just another raw media dat
 * [[identifying the basic Builder operations|BasicBuildingOperations]] and [[planning the Implementation|PlanningNodeCreatorTool]]
 * [[how to handle »attached placement«|AttachedPlacementProblem]]
 * working out the [[basic building situations|BuilderPrimitives]] and [[mechanics of rendering|RenderMechanics]]
+* how to classify and [[describe media stream types|StreamType]]
 
@@ -1784,7 +1832,7 @@ __5/2008__: the allocation mechanism can surely be improved later, but for now I &rarr; see also LoadingMedia
-
+
Of course: Cinelerra currently leaks memory and crashes regularilly. For the newly written code, besides retaining the same level of performance, a main goal is to use methods and techniques known to support the writing of quality code. So, besides the MultithreadConsiderations, a solid strategy for managing the ownership of allocated memory blocks is necessary right from start.
 
 !Problems
@@ -1810,11 +1858,11 @@ For the case here in question this seems to be the ''resource allocation is cons
 !!!rather harmless
 * Frames (buffers), because they belong to a given [[RenderProcess (=StateProxy)|StateProxy]] and are just passed in into the individual [[ProcNode]]s. This can be handled consistently with conventional methods.
 * each StateProxy belongs to one top-level call to the [[Controller-Facade|Controller]]
-* same for the builder tools
+* similar for the builder tools, which belong to a build process. Moreover, they are pooled and reused.
 * the EDL and the defined [[Asset]]s belong together to one Session. If the Session is closed, this means a internal shutdown of the whole ProcLayer, i.e. closing of all GUI representations and terminating all render processes. If these calles are implemented as blocking operations, we can assert that as long as any GUI representation or any render process is running, there is a valid Session and EDL.
 
 !using Factories
-And, last but not least, doing all actual allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides, the ProcLayer code shouldn't issue "new" and "delete" when it comes in hand, rather it should use some centralized [[Factories]] for all allocation and freeing, so we can redirect these calls down to the backend, which may use pooling or special placement allocators or the like. The rationale is, for modern hardware/architectures, care has to be taken with heap allocations, esp. with many small objects and irregular usage patterns.
+And, last but not least, doing large scale allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides, the ProcLayer code shouldn't issue "new" and "delete" when it comes in hand, rather it should use some centralized [[Factories]] for all allocation and freeing, so we can redirect these calls down to the backend, which may use pooling or special placement allocators or the like. The rationale is, for modern hardware/architectures, care has to be taken with heap allocations, esp. with many small objects and irregular usage patterns.
 
@@ -2715,7 +2763,7 @@ Besides, they provide an important __inward interface__ for the [[ProcNode]]s, w ''Status'': started out as design draft in summer '07, Ichthyo is now in the middle of a implementing the foundations and main structures in C++ * basic [[AssetManager]] working * [[Builder]] implementation is on the way (&rarr;[[more|BuilderPrimitives]]) -* currently working out how to wire and operate procesing nodes (&rarr;[[more|RenderMechanics]]) +* made a first draft of how to wire and operate procesing nodes (&rarr;[[more|RenderMechanics]]) <<< !Summary @@ -3044,7 +3092,7 @@ At first sight the link between asset and clip-MO is a simple logical relation b [img[Entities comprising the Render Engine|uml/fig128389.png]]
-
+
Below are some notes regarding details of the actual implementation of the render process and processing node operation. In the description of the [[render node operation protocol|NodeOperationProtocol]] and the [[mechanics of the render process|RenderMechanics]], these details were left out deliberately.
 
 !Layered structure of State
@@ -3060,18 +3108,19 @@ Some data processors simply require to work on multiple channels simultanously,
 [>img[uml/fig132357.png]]
 Every node is actually decomposed into three parts
 * an interface container of a ProcNode subclass
-* an {{{const}}} WiringDescriptor, which is actually parametrized to a subtype encoding details of the intended operation
-* an StateAdapter object created on the stack for each {{{pull()}}} call and configured specifically for the intended operation
-Thus, the outer container can be changed polymorphically to support the different kinds of nodes (large-scale view). The actual wiring of the nodes is contained in the WiringDescriptor, including the {{{process()}}} function pointer. Additionally, this WiringDescriptor knows the actual type of the StateAdapter to create, and this actual type has been chosen by the builder such as to select details of the desired operation of this mode, for example caching / no caching or maybe ~OpenGL rendering or the special case of a node pulling directly from a source reader. Most of this configuration is done by selecting the right template specialisation within the builder; thus in the critical path most of the calls can be inlined
+* an {{{const}}} WiringDescriptor, which is actually parametrized to a subtype encoding details of how to carry out the intended operation
+* the Invocation state created on the stack for each {{{pull()}}} call. It is comprised of references to an StateAdapter object  and the current overall process state, the WiringDescriptor, and finally a table of suitable buffer handles
+Thus, the outer container can be changed polymorphically to support the different kinds of nodes (large-scale view). The actual wiring of the nodes is contained in the WiringDescriptor, including the {{{process()}}} function pointer. Additionally, this WiringDescriptor knows the actual type of the operation Strategy, and this actual type has been chosen by the builder such as to select details of the desired operation of this node, for example caching / no caching or maybe ~OpenGL rendering or the special case of a node pulling directly from a source reader. Most of this configuration is done by selecting the right template specialisation within the builder; thus in the critical path most of the calls can be inlined
 
-!!!! composing the actual StateAdapter
-As shown in the class diagram to the right, the actual implementation is assembled by chaining together the various policy classes governing parts of the node operation, like Caching, in-Place calculation capability, etc. (&rarr; see [[here|StateAdapter]] for details). The rationale is that we can allocate at runtime a StateProxy object directly on the stack with the necessary buffer table size and an precisely tailored and mostly inlined implementation of the call sequence for "calculating the predecessor nodes". We //do employ//&nbsp; some virtual calls for the buffer management in order to avoid coupling the policy classes to the actual number of in/out buffers. (As of 6/2008, this is mainly a precaution to be able to control the number of generated template instances. If we ever get in the region of several hundred individual specialisations, we'd need to separate out the allocation of the "wiring table" into a hand-made stack-like buffer allocated from the heap.)
+!!!! composing the actual operation Strategy
+As shown in the class diagram to the right, the actual implementation is assembled by chaining together the various policy classes governing parts of the node operation, like Caching, in-Place calculation capability, etc. (&rarr; see [[here|WiringDescriptor]] for details). The rationale is that the variable part of the Invocation data is allocated at runtime directly on the stack, while a precisely tailored call sequence for "calculating the predecessor nodes" can be defined out of a bunch of simple building blocks. This helps avoiding "spaghetti code", which would be especially dangerous because of the large number of different execution paths to get right. Additionally, a nice side effect of this implementation technique is that a good deal of the implementation is eligible to inlining.
+We //do employ//&nbsp; some virtual calls for the buffer management in order to avoid coupling the policy classes to the actual number of in/out buffers. (As of 6/2008, this is mainly a precaution to be able to control the number of generated template instances. If we ever get in the region of several hundred individual specialisations, we'd need to separate out the allocation of the "buffer table" into a hand-made stack-like buffer allocated from the heap.)
 
 !Rules for buffer allocation and freeing
 * only output buffers are allocated. It is //never necessary//&nbsp; to allocate input buffers!
 * buffers are to be allocated as late as possible, typically just before invoking {{{process()}}}
-* buffers are allways allocated by calling to the preceeding StateAdapter in the callstack ("parent stae"), because of the possibility to write to cache.
-* {{{pull()}}} returns the buffer-ID of the single output requested by this call. Using this ID, the caller may retrieve the actual buffer holding the result from the "current state" StaeProxy.
+* buffers are allways allocated by calling to the preceeding StateAdapter in the callstack ("parent stae"), because of the possibility of writing the result to cache.
+* {{{pull()}}} returns a handle for the single output requested by this call. Using this ID, the caller may retrieve the actual buffer holding the result from the "current state" StaeProxy.
 * any other buffers filled with results in the course of the same {{{process()}}} call can be released immediately before returning from the {{{pull()}}}
 * similar, and input buffers are to be released immediately after the {{{process()}}} call, but before returing from this {{{pull()}}}
 * buffers are allways released by calling to the "current state" (which is a StateProxy), providing the buffer-ID to be released
@@ -3157,8 +3206,9 @@ The Session object is a singleton &mdash; actually it is a »~PImpl«-Facade
 * a collection of ''global Pipes''
 * the ''Fixture'' with a possibility to [[(re)build it|PlanningBuildFixture]]
-
-
The [[Session]] (sometimes also called //Project//) contains all informations and objects to be edited by the User. It can be saved and loaded. The individual Objects within the Session, i.e. Clips, Media, Effects, are contained in one (or several) collections within the Session, which we call [[EDL (Edit Decision List)|EDL]]. Moreover, the sesion contains references to all the Media files used, and it contains various default or user defined configuration, all being represented as [[Asset]]. At any given time, there is //only one current session// opened within the application.
+
+
The [[Session]] (sometimes also called //Project// ) contains all informations and objects to be edited by the User. It can be saved and loaded. The individual Objects within the Session, i.e. Clips, Media, Effects, are contained in one (or several) collections within the Session, which we call [[EDL (Edit Decision List)|EDL]]. Moreover, the sesion contains references to all the Media files used, and it contains various default or user defined configuration, all being represented as [[Asset]]. At any given time, there is //only one current session// opened within the application.
+The Session is close to what is visible in the GUI. From a user's perspective, you'll find a timeline-like structure, where various Media Objects are arranged and placed. The available building blocks and the rules how they can be combined together form Lumiera's [[high-level data model|HighLevelModel]]. Basically, besides the [[media objects|MObjects]] there are data connections and all processing is organized around processing chains or [[pipes|Pipe]], which can be either global (in the Session) or local (in real or virtual clips)
 
 !!!larger projects
 For larger editing projects the simple structure of a session containing "the" timeline is not sufficient. Rather, we have several timelines, e.g. one for each scene. Or we could have several layered or nested timelines (compositional work, multimedia productions). To support these cases without making the default case more complicated, Lumiera introduces a //focus// for selecting the //current EDL,// which will receive all editing operations.
@@ -3175,6 +3225,8 @@ The possibility of having multiple ~EDLs helps organizing larger projects. Each
 !!!default configuration
 While all these possibilities may seem daunting, there is a simple default configuration loaded into any pristine new session:
 It will contain a global video and audio out pipe, just one EDL with a single track; this track will have a internal video and audio pipe (bus) configured with one fading device sending to the global output ports. So, by adding some clip with a simple absolute placement to this track and some time position, the clip gets connected and rendered, after [[(re)building|PlanningBuildFixture]] the [[Fixture]] and passing the result to the [[Builder]] &mdash; and using the resulting render nodes network (Render Engine).
+
+&rarr; [[anatomy of the high-level model|HighLevelModel]]
 
@@ -3247,32 +3299,8 @@ if (oldText.indexOf("SplashScreen")==-1) } //}}}
-
-
A small (in terms of storage) and specifically configured StateProxy object which is created on the stack for each individual {{{pull()}}} call. The actual type of this object is composed out of several building blocks (policy classes) and placed by the builder as a template parameter on the WiringDescriptor of the individual ProcNode. This happens in the WiringFactory in file {{{nodewiring.cpp}}}, which consequently contains all the possible combinations (pre)generated at compile time.
-
-!building blocks
-* ''Caching'': whether the result frames of this processing step will be communicated to the Cache and thus could be fetched from there instead of actually calculating them.
-* ''Process'': whether this node does any calculations on it's own or just pulls from a source
-* ''Inplace'': whether this node is capable of processing the result "in-place", thereby overwriting the input buffer
-* ''Multiout'': whether this node produces multiple output channels/frames in one processing step
-
-!!implementation
-!!!!Caching
-When a node participates in ''caching'', a result frame may be pulled immediately from cache instead of calculating it. Moreover, //any output buffer//&nbsp; of this node will be allocated //within the cache.// Consequently, caching interferes with the ability of the next node to calculate "in-Place". In the other case, when ''not using the cache'', the {{{pull()}}} call immediately starts out with calling down to the predecessor nodes, and the allocation of output buffer(s) is always delegated to the parent state (i.e. the StateProxy pulling results from this node). 
-
-Generally, buffer allocation requests from predecessor nodes (while being pulled by this node) will either be satisfied by using the "current state", or treated as if they were our own output buffers when this node is in-Place capable.
-
-!!!!Multiple Outputs
-Some simplifications are possible in the default case of a node producing just ''one single output'' stream. Otherwise, we'd have to allocate multiple output buffers, and then, after processing, select the one needed as a result and deallocate the superfluous further buffers.
-
-!!!!in-Place capability
-If a node is capable of calculating the result by ''modifying it's input'' buffer(s), an important performance optimization is possible, because in a chain of in-place capable nodes, we don't need any buffer allocations. But, on the other hand, this optimization may collide with the caching, because a frame retrieved from cache must not be modified.
-Without this optimization, in the base case each processing needs an input and an output. Exceptionally, we could think of special nodes which //require// to process in-place, in which case we'd need to provide a copy of the input buffer to work on under certain circumstances. 
-
-!!!!Processing
-If ''not processing'' we don't have any input buffers, instead we get our output buffers from an external source.
-Otherwise, in the default case of actually ''processing'' out output, we have to organize input buffers, allocate output buffers, call the {{{process()}}} function of the WiringDescriptor and finally release the input buffers.
-
+
+
A small (in terms of storage) and specifically configured StateProxy object which is created on the stack for each individual {{{pull()}}} call. It is part of the invocation state of such a call and participates in the buffer management. Thus, in a calldown sequence of {{{pull()}}} calls we get a corresponding sequence of "parent" states. At each level, the &rarr; WiringDescriptor of the respective node defines a Strategy how the call is passed on.
An Object representing a //Render Process// and containing associated state information.
@@ -3282,6 +3310,76 @@ Otherwise, in the default case of actually ''processing'' out output, we have to
 * in a future version, it may also encapsulate the communication in a distributed render farm
 
+
+
The stream Prototype is part of the specification of a media stream's type. It is a semantic (or problem domain oriented) concept and should be distinguished from the actual implementation type of the media stream. The latter is provided by an [[library implementation|StreamTypeImplFacade]]. While there are some common predefined prototypes, mostly, they are defined within the concrete [[Session]] according to the user's needs. 
+
+Prototypes form an open (extensible) collection, though each prototype belongs to a specific media kind ({{{VIDEO, IMAGE, AUDIO, MIDI,...}}}). The ''distinguishing property'' of a stream prototype is that any [[Pipe]] can process //streams of a specific prototype only.// Thus, two streams with different prototype can be considered "something quite different" from the users point of view, while two streams belonging to the same prototype can be considered equivalent (and will be converted automatically when their implementation types differ). Note this definition is //deliberately fuzzy,// because it depends on the actual situation of the project in question.
+
+Consequently, as we can't get away with an fixed Enum of all stream prototypes, the implementation must rely on a query interface. The intention is to provide a basic set of rules for deciding queries about the most common stream prototypes; besides, a specific session may inject additional rules or utilize a completely different knowledge base. Thus, for a given StreamTypeDescriptor specifying a prototype
+* we can get a [[default|DefaultsManagement]] implementation type
+* we can get a default prototype to a given implementation type by a similar query
+* we can query if a implementation type in question can be //subsumed// under this prototype
+* we can determine if another prototype is //convertible//
+
+!!Examples
+NTSC and PAL video, video versus digitized film, HD video versus SD video, 3D versus flat video, cinemascope versus 4:3, stereophonic versus monaural, periphonic versus panoramic sound, Ambisonics versus 5.1, dolby versus dts,...
+
+
+
+
//how to classify and describe media streams//
+Media data is understood to appear structured as stream(s) over time. While there may be an inherent internal structuring, at a given perspective ''any stream is a unit and homogeneous''. In the context of digital media data processing, streams are always ''quantized'', which means they appear as a temporal sequence of data chunks called ''frames''.
+
+! Terminology
+* __Media__ is comprised of a set of streams or channels
+* __Stream__ denotes a homogeneous flow of media data of a single kind
+* __Channel__ denotes a elementary stream, which can't be further separated in the given context
+* all of these are delivered and processed in a smallest unit called __Frame__. Each frame corresponds to a //time interval.//
+* a __Buffer__ is a data structure capable of holding a Frame of media data.
+* the __~Stream-Type__ describes the kind of media data contained in the stream
+
+! Problem of Stream Type Description
+Media types vary largely and exhibit a large number of different properties, which can't be subsumed under a single classification scheme. But on the other hand, we want to deal with media objects in a uniform and generic manner, because generally all kinds of media behave somewhat similar. But the problem is, these similarities disappear when describing media with logical precision. Thus we are forced into specialized handling and operations for each kind of media, while we want to implement a generic handling concept.
+
+! Stream Type handling in the Proc-Layer
+!! Identification
+A stream type is denoted by a StreamTypeID, which is an identifier, acting as an unique key for accessing information related to the stream type. It corresponds to an StreamTypeDescriptor record, containing an &mdash; //not necessarily complete// &mdash; specification of the stream type, according to the classification detailed below.
+
+!! Classification
+Within the Proc-Layer, media streams are treated largely in a similar manner. But, looking closer, note everything can be connected together, while on the other hand there may be some classes of media streams which can be considered //equivalent// in most respects. Thus, it seems reasonable to separate the distinction between various media streams into several levels
+* Each media belongs to a fundamental ''kind'' of media, examples being __Video__, __Image__, __Audio__, __MIDI__,... Media streams of different kind can be considered somewhat "completely separate" &mdash; just the handling of each of those media kinds follows a common //generic pattern// augmented with specialisations. Basically, it is //impossible to connect// media streams of different kind. Under some circumstances there may be the possibility of a //transformation// though. For example, a still image can be incorporated into video, sound may be visualized, MIDI may control a sound synthesizer.
+* Below the level of distinct kinds of media streams, within every kind we have an open ended collection of ''prototypes'', which, when compared directly may each be quite distinct and different, but which may be //rendered//&nbsp; into each other. For example, we have stereoscopic (3D) video and we have the common flat video lacking depth information, we have several spatial audio systems (Ambisonics, Wave Field Synthesis), we have panorama simulating sound systems (5.1, 7.1,...), we have common stereophonic and monaural audio. It is considered important to retain some openness and configurability within this level of distinction, which means this classification should better be done by rules then by setting up a fixed property table. For example, it may be desirable for some production to distinguish between digitized film and video NTSC and PAL, while in another production everything is just "video" and can be converted mostly automatically. The most noticeable consequence of such a distinction is that any Bus or [[Pipe]] is always limited to a media stream of a single prototype. (&rarr; [[more|StreamPrototype]])
+* Besides the distinction by prototypes, there are the various media ''implementation types''. This classification is not necessarily hierarchically related to the prototype classification, while in practice commonly there will be some sort of dependency. For example, both stereophonic and monaural audio may be implemented as 96kHz 24bit PCM with just a different number of channel streams, as well as we may have a dedicated stereo audio stream with two channels multiplexed into a single stream. For dealing with media streams of various implementation type, we need library routines, which also yield a type classification system. Most notably, for raw sound and video data we use the GAVL library, which defines a classification system for buffers and streams.
+* Besides the type classification detailed thus far, we introduce an ''intention tag''. This is a synthetic classification owned by Lumiera and used for internal wiring decisions. Currently (8/08), we recognize the following intention tags: __Source__, __Raw__, __Intermediary__ and __Target__. Only media streams tagged as __Raw__ can be processed.
+
+!! Media handling requirements involving stream type classification
+* set up a buffer and be able to create/retrieve frames of media data.
+* determine if a given media data source and sink can be connected, and how.
+* determine and enumerate the internal structure of a stream.
+* discover processing facilities
+
+
+
+
A description and classification record usable to find out about the properties of a media stream. The stream type descriptor can be accessed using an unique StreamTypeID. The information contained in this descriptor record can intentionally be //incomplete,// in which case the descriptor captures a class of matching media stream types. The following information is maintained:
+* fundamental ''kind'' of media: {{{VIDEO, IMAGE, AUDIO, MIDI,...}}}
+* stream ''prototype'': this is the abstract high level media type, like NTSC, PAL, Film, 3D, Ambisonics, 5.1, monaural,...
+* stream ''implementation type'' accessible by virtue of an StreamTypeImplFacade
+* the ''intended usage category'' of this stream: {{{SOURCE, RAW, INTERMEDIARY, TARGET}}}.
+&rarr; see &raquo;[[Stream Type|StreamType]]&laquo; detailed specification
+&rarr; more [[about prototypes|StreamPrototype]]
+
+
+
This ID is an symbolic key linked to a StreamTypeDescriptor. The predicate {{{stream(ID)}}} specifies a media stream with the StreamType as detailed by the corresponding descriptor (which may contain complete or partial data defining the type).
+
+
+
Common interface for dealing with the implementation of media stream data. From a high level perspective, the various kinds of media ({{{VIDEO, IMAGE, AUDIO, MIDI,...}}}) exhibit similar behaviour, while on the implementation level not even the common classification can be settled down to a complete general and useful scheme. Thus, we need separate library implementations for deailing with the various sorts of media data, all providing at least a set of basic operations:
+* set up a buffer
+* create or accept a frame
+* get an tag describing the precise implementation type
+* ...?
+
+&rarr; see also &raquo;[[Stream Type|StreamType]]&laquo;
+
+
This design lays great emphasis on separating all those components and subsystems, which are considered not to have a //natural link// of their underlying concepts. This often means putting some additional constraints on the implementation, so basically we need to rely on the actual implementation to live up to this goal. In many cases it may seem to be more natural to "just access the necessary information". But on the long run this coupling of not-directly related components makes the whole codebase monolithic and introduces lots of //accidental complexity.//
 
@@ -4561,10 +4659,10 @@ Using transitions is a very basic task and thus needs viable support by the GUI.
 Because of this experience, ichthyo wants to support a more general case of transitions, which have N output connections, behave similar to their "simple" counterpart, but leave out the mixing step. As a plus, such transitions can be inserted at the source ports of N clips or between any intermediary or final output pipes as well. Any transition processor capable of handling this situation should provide some flag, in order to decide if he can be placed in such a manner. (wichin the builder, encountering a  inconsistently placed transition is just an [[building error|BuildingError]])
 
-
+
A ''~Meta-Clip'' or ''Virtual Clip'' (both are synonymous) denotes a clip which doesn't just pull media streams out of a source media asset, but rather provides the results of rendering a complete sub-network. In all other respects it behaves exactly like a "real" clip, i.e. it has [[source ports|ClipSourcePort]], can have attached effects (thus forming a local render pipe) and can be placed and combined with other clips. Depending on what is wired to the source ports, we get two flavours:
-* a __placeholder clip__; has no "embedded" content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
-* a __nested EDL __ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to "contain" the objects of the nested EDL. Typically, you'd also [[configure the tracks|TrackHandling]] of the "inner" EDL such as to connect any output to the source ports of the Virtual Clip.
+* a __placeholder clip__ has no "embedded" content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
+* a __nested EDL __ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to "contain" the objects of the nested EDL. Typically, this also [[configures the tracks|TrackHandling]] of the "inner" EDL such as to connect any output to the source ports of the Virtual Clip.
 
 Like any "real" clip, Virtual Clips have a start offset and a length, which will simply translate into an offset of the frame number pulled from the Virtual Clip's source connection or embedded EDL, making it possible to cut, splice, trim and roll them as usual. This of course implies we can have several instances of the same virtual clip with different start offset and length placed differently. The only limitation is that we can't handle cyclic dependencies for pulling data (which has to be detected and flagged as an error by the builder)
 
@@ -4649,6 +4747,33 @@ In case it's not already clear: we don't have "the" Render Engine, rat The &raquo;current setup&laquo; of the objects in the EDL is sort of a global state. Same holds true for the Controller, as the Engine can be at playback, it can run a background render or scrub single frames. But the whole complicated subsystem of the Builder and one given Render Engine configuration can be made ''stateless''. As a benefit of this we can run this subsystems multi-threaded without the need of any precautions (locking, synchronizing). Because all state information is just passed in as function parameters and lives in local variables on the stack, or is contained in the StateProxy which represents the given render //process// and is passed down as function parameter as well. (note: I use the term "stateless" in the usual, slightly relaxed manner; of course there are some configuration values contained in instance variables of the objects carrying out the calculations, but this values are considered to be constant over the course of the object usage).
+
+
Each [[processing node|ProcNode]] contains a stateless ({{{const}}}) descriptor detailing the inputs, outputs and predecessors. Moreover, this descriptor contains the configuration of the call sequence yielding the &raquo;data pulled from predecessor(s)&laquo;. The actual type of this object is composed out of several building blocks (policy classes) and placed by the builder as a template parameter on the WiringDescriptor of the individual ProcNode. This happens in the WiringFactory in file {{{nodewiring.cpp}}}, which consequently contains all the possible combinations (pre)generated at compile time.
+
+!building blocks
+* ''Caching'': whether the result frames of this processing step will be communicated to the Cache and thus could be fetched from there instead of actually calculating them.
+* ''Process'': whether this node does any calculations on it's own or just pulls from a source
+* ''Inplace'': whether this node is capable of processing the result "in-place", thereby overwriting the input buffer
+* ''Multiout'': whether this node produces multiple output channels/frames in one processing step
+
+!!implementation
+!!!!Caching
+When a node participates in ''caching'', a result frame may be pulled immediately from cache instead of calculating it. Moreover, //any output buffer//&nbsp; of this node will be allocated //within the cache.// Consequently, caching interferes with the ability of the next node to calculate "in-Place". In the other case, when ''not using the cache'', the {{{pull()}}} call immediately starts out with calling down to the predecessor nodes, and the allocation of output buffer(s) is always delegated to the parent state (i.e. the StateProxy pulling results from this node). 
+
+Generally, buffer allocation requests from predecessor nodes (while being pulled by this node) will either be satisfied by using the "current state", or treated as if they were our own output buffers when this node is in-Place capable.
+
+!!!!Multiple Outputs
+Some simplifications are possible in the default case of a node producing just ''one single output'' stream. Otherwise, we'd have to allocate multiple output buffers, and then, after processing, select the one needed as a result and deallocate the superfluous further buffers.
+
+!!!!in-Place capability
+If a node is capable of calculating the result by ''modifying it's input'' buffer(s), an important performance optimization is possible, because in a chain of in-place capable nodes, we don't need any buffer allocations. But, on the other hand, this optimization may collide with the caching, because a frame retrieved from cache must not be modified.
+Without this optimization, in the base case each processing needs an input and an output. Exceptionally, we could think of special nodes which //require// to process in-place, in which case we'd need to provide it with a copy of the input buffer to work on. 
+
+!!!!Processing
+If ''not processing'' we don't have any input buffers, instead we get our output buffers from an external source.
+Otherwise, in the default case of actually ''processing'' out output, we have to organize input buffers, allocate output buffers, call the {{{process()}}} function of the WiringDescriptor and finally release the input buffers.
+
+
The purpose of automation is to vary a parameter of some data processing instance in the course of time while rendering. Thus, automation encompasses all the variability within the render network //which is not a structural change.//