Merge work on OutputDesignation and OutputMapping

Merge commit 'prg@ichthyostega.de/session_signature'
This commit is contained in:
Fischlurch 2010-11-28 05:29:53 +01:00
commit f947f4522c
57 changed files with 1599 additions and 486 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -125,6 +125,8 @@ namespace lumiera {
LUMIERA_ERROR_DECLARE (WRONG_TYPE); ///< runtime type mismatch
LUMIERA_ERROR_DECLARE (ITER_EXHAUST); ///< end of sequence reached
LUMIERA_ERROR_DECLARE (BOTTOM_VALUE); ///< invalid or NIL value
LUMIERA_ERROR_DECLARE (UNCONNECTED); ///< missing connection
/** Macro for creating derived exception classes properly

View file

@ -82,6 +82,7 @@ namespace lumiera {
LUMIERA_ERROR_DEFINE (WRONG_TYPE, "runtime type mismatch");
LUMIERA_ERROR_DEFINE (ITER_EXHAUST, "end of sequence reached");
LUMIERA_ERROR_DEFINE (BOTTOM_VALUE, "invalid or NIL value");
LUMIERA_ERROR_DEFINE (UNCONNECTED, "missing connection");
} // namespace error

View file

@ -41,7 +41,7 @@
**
** Most of these trait templates rely on a creative use of function overloading. The C++ standard
** requires the compiler <i>silently to drop</i> any candidate of overload resolution which has
** gotten an invalid function signature as a result of instantiating a template (type). This allow
** gotten an invalid function signature as a result of instantiating a template (type). This allows
** us to set up kind of a "trap" for the compiler: we present two overloaded candidate functions
** with a different return type; by investigating the resulting return type we're able to figure
** out the overload actually picked by the compiler.

View file

@ -40,9 +40,10 @@
** usage context to provide the correct function signature; only when using a
** virtual function for the re-access, we can perform at least a runtime-check.
**
** Thus there are various flavours for actually implementing this idea, and the
** Thus there are various flavours for actually implementing this idea, and
** picking a suitable implementation depends largely on the context. Thus we
** provide a common and expect the client code to pick an implementation policy.
** provide a common frontend for access and expect the client code to pick
** a suitable implementation policy.
**
** @see control::Mutation usage example
** @see function-erasure-test.cpp

View file

@ -30,7 +30,7 @@
** this situation arises when dealing with functor objects.
**
** These templates help with building custom objects and wrappers based on
** this pattern: InPlaceAnyHolder provides an buffer for the target objects
** this pattern: lib::InPlaceAnyHolder provides a buffer for target objects
** and controls access through a two-layer capsule; while the outer container
** exposes a neutral interface, the inner container keeps track of the actual
** type by means of a vtable. OpaqueHolder is built on top of InPlaceAnyHolder
@ -45,7 +45,11 @@
** of course this rules out anything beyond re-accessing the embedded object
** by knowing it's exact type. Generally speaking, re-accessing the concrete
** object requires knowledge of the actual type, similar to boost::any
** (but contrary to OpaqueHolder the latter uses heap storage).
** (but contrary to OpaqueHolder the latter uses heap storage).
**
** As a supplement, a more lightweight implementation is provided as
** lib::InPlaceBuffer, requiring just the object storage and lacking the
** ability to track the actual type of the embedded object.
**
** Using this approach is bound to specific stipulations regarding the
** properties of the contained object and the kind of access needed.

View file

@ -45,8 +45,19 @@ namespace lumiera {
/**
* Generic query interface for retrieving objects matching
* some capability query
* Generic query interface for retrieving objects
* matching the given capability query
* @note until really integrating a rules based system
* this is a dummy placeholder implementation
* based on a dressed-up std::string
* @warning in this preliminary implementation, the
* given query-string is used as-is, without any
* normalisation. Moreover, as espeically the
* fake-configrules match by string comparision,
* this may led to unexpected mis-matches.
* @todo the »real thing« should be based on a
* normalised syntax tree representation
* of the atoms in the query.
*/
template<class OBJ>
class Query : public std::string

View file

@ -92,6 +92,7 @@ liblumiprocmobject_la_SOURCES = \
$(liblumiprocmobject_la_srcdir)/interpolator.cpp \
$(liblumiprocmobject_la_srcdir)/mobject-ref.cpp \
$(liblumiprocmobject_la_srcdir)/mobject.cpp \
$(liblumiprocmobject_la_srcdir)/output-designation.cpp \
$(liblumiprocmobject_la_srcdir)/parameter.cpp \
$(liblumiprocmobject_la_srcdir)/paramprovider.cpp \
$(liblumiprocmobject_la_srcdir)/placement.cpp
@ -149,6 +150,7 @@ liblumiprocmobjectsession_la_SOURCES = \
$(liblumiprocmobjectsession_la_srcdir)/allocation.cpp \
$(liblumiprocmobjectsession_la_srcdir)/auto.cpp \
$(liblumiprocmobjectsession_la_srcdir)/binding.cpp \
$(liblumiprocmobjectsession_la_srcdir)/bus-mo.cpp \
$(liblumiprocmobjectsession_la_srcdir)/clip.cpp \
$(liblumiprocmobjectsession_la_srcdir)/compoundclip.cpp \
$(liblumiprocmobjectsession_la_srcdir)/constraint.cpp \

View file

@ -86,6 +86,7 @@ namespace asset {
//NOBUG_DECLARE_FLAG (assetmem);
typedef size_t HashVal; /////////////////TICKET #722
/**
* thin wrapper around a size_t hash ID
@ -103,10 +104,10 @@ namespace asset {
class ID
{
public:
const size_t hash;
ID (size_t id) : hash(id) {}
const HashVal hash;
ID (HashVal id) : hash(id) {}
ID (const KIND& asset) : hash(asset.getID()) {}
operator size_t() const { return hash; }
operator HashVal() const { return hash; }
};
class DB;

View file

@ -23,8 +23,7 @@
#include "proc/asset/codec.hpp"
namespace asset
{
namespace asset {

View file

@ -28,8 +28,7 @@
namespace asset
{
namespace asset {
/**
* description of some media data decoder or encoder facility
@ -38,8 +37,8 @@ namespace asset
{
};
} // namespace asset
#endif

View file

@ -32,8 +32,7 @@ using std::vector;
namespace asset
{
namespace asset {
/**

View file

@ -59,7 +59,7 @@ namespace asset {
class ID<Media> : public ID<Asset>
{
public:
ID (size_t id);
ID (HashVal id);
ID (const Media&);
};
@ -130,7 +130,7 @@ namespace asset {
// definition of ID<Media> ctors is possible now,
// after providing full definition of class Media
inline ID<Media>::ID(size_t id) : ID<Asset> (id) {};
inline ID<Media>::ID(HashVal id) : ID<Asset> (id) {};
inline ID<Media>::ID(const Media& media) : ID<Asset> (media.getID()) {};

View file

@ -55,7 +55,7 @@ namespace asset {
class ID<Meta> : public ID<Asset>
{
public:
ID (size_t id);
ID (HashVal id);
ID (const Meta&);
};
@ -84,7 +84,7 @@ namespace asset {
// definition of ID<Meta> ctors is possible now,
// after providing full definition of class Proc
inline ID<Meta>::ID(size_t id) : ID<Asset> (id) {};
inline ID<Meta>::ID(HashVal id) : ID<Asset> (id) {};
inline ID<Meta>::ID(const Meta& meta) : ID<Asset> (meta.getID()) {};
typedef P<Meta> PMeta;

View file

@ -22,6 +22,7 @@
#include "proc/asset/pipe.hpp"
#include "proc/assetmanager.hpp"
#include "lib/util.hpp"
using util::isnil;
@ -57,9 +58,20 @@ namespace asset {
PPipe
Pipe::query (string properties)
{
return Struct::retrieve (Query<Pipe> (properties));
}
{
return Struct::retrieve (Query<Pipe> (properties));
}
/** @param id asset-ID of the pipe to retrieve
* @throw error::Invalid when not found
*/
PPipe
Pipe::lookup (ID<Pipe> id)
{
return AssetManager::instance().getAsset(id);
}
void
Pipe::switchProcPatt (PProcPatt& another)

View file

@ -44,7 +44,7 @@ namespace asset {
class ID<Pipe> : public ID<Struct>
{
public:
ID (size_t id);
ID (HashVal id);
ID (const Pipe&);
};
@ -86,13 +86,16 @@ namespace asset {
void switchProcPatt (PProcPatt& another);
/** convenience shortcut for retrieving default configured pipes */
static PPipe query (string properties) ;
static PPipe query (string properties);
/** convenience shortcut for lookup by id */
static PPipe lookup (ID<Pipe> id);
};
// catch up with postponed definition of ID<Struct> ctors...
//
inline ID<Pipe>::ID(size_t id) : ID<Struct> (id) {};
inline ID<Pipe>::ID(HashVal id) : ID<Struct> (id) {};
inline ID<Pipe>::ID(Pipe const& pipe) : ID<Struct> (pipe.getID()) {};

View file

@ -23,29 +23,27 @@
#include "proc/asset/preview.hpp"
namespace asset
{
namespace asset {
namespace
namespace {
/** @internal derive a sensible asset ident tuple when creating
* a proxy placeholder media based on some existing asset::Media
* @todo getting this one right is important for the handling
* of "proxy editing"....
*/
const Asset::Ident
createProxyIdent (const Asset::Ident& mediaref)
{
/** @internal derive a sensible asset ident tuple when creating
* a proxy placeholder media based on some existing asset::Media
* @todo getting this one right is important for the handling
* of "proxy editing"....
*/
const Asset::Ident
createProxyIdent (const Asset::Ident& mediaref)
{
string name (mediaref.name + "-proxy"); // TODO something sensible here; append number, sanitise etc.
Category category (mediaref.category);
TODO ("put it in another subfolder within the same category??");
return Asset::Ident (name, category,
mediaref.org,
mediaref.version );
}
string name (mediaref.name + "-proxy"); // TODO something sensible here; append number, sanitise etc.
Category category (mediaref.category);
TODO ("put it in another subfolder within the same category??");
return Asset::Ident (name, category,
mediaref.org,
mediaref.version );
}
}//(End)implementation helper
@ -62,8 +60,8 @@ namespace asset
this->defineDependency (mediaref);
UNIMPLEMENTED ("do something to setup proxy media");
}
} // namespace asset

View file

@ -28,9 +28,8 @@
namespace asset
{
namespace asset {
/**
* special placeholder denoting an alternative version of the media data,
* typically with lower resolution ("proxy media")
@ -41,8 +40,8 @@ namespace asset
Preview (Media& mediaref);
friend class MediaFactory;
};
} // namespace asset
#endif

View file

@ -27,15 +27,8 @@
#include "include/logging.h"
namespace asset
{
namespace asset {
namespace // Implementation details
{
/** helper: .....*/
}
ProcFactory Proc::create; ///< storage for the static ProcFactory instance

View file

@ -26,7 +26,7 @@
** For the different <i>Kinds</i> of Assets, we use sub-interfaces inheriting
** from the general Asset interface. To be able to get asset::Proc instances
** directly from the AssetManager, we define a specialisation of the Asset ID.
**
**
** @see asset.hpp for explanation
** @see ProcFactory creating concrete asset::Proc instances
**
@ -57,12 +57,12 @@ namespace asset {
class ID<Proc> : public ID<Asset>
{
public:
ID (size_t id);
ID (HashVal id);
ID (const Proc&);
};
/**
* key abstraction: data processing asset
* @todo just a stub, have to figure out what a asset::Proc is
@ -94,18 +94,18 @@ namespace asset {
virtual ProcFunc*
resolveProcessor() const =0;
protected:
Proc (const Asset::Ident& idi) : Asset(idi) {} //////////////TODO
friend class ProcFactory;
};
// definition of ID<Proc> ctors is possible now,
// after providing full definition of class Proc
inline ID<Proc>::ID(size_t id) : ID<Asset> (id) {};
inline ID<Proc>::ID(HashVal id) : ID<Asset> (id) {};
inline ID<Proc>::ID(const Proc& proc) : ID<Asset> (proc.getID()) {};
@ -120,11 +120,11 @@ namespace asset {
typedef P<asset::Proc> PType;
PType operator() (Asset::Ident& key); ////////////TODO define actual operation
};
} // namespace asset
#endif

View file

@ -37,15 +37,15 @@ namespace asset {
using lumiera::P;
using lib::Symbol;
class Proc;
class ProcPatt;
class BuildInstruct;
typedef P<const asset::Proc> PProc;
typedef P<const asset::ProcPatt> PProcPatt;
typedef vector<BuildInstruct> InstructionSequence;
typedef vector<BuildInstruct> InstructionSequence;
/**
* "Processing Pattern" is a structural Asset
* representing information how to build some part
@ -56,7 +56,7 @@ namespace asset {
{
InstructionSequence instructions_;
ProcPatt (const Asset::Ident&, const InstructionSequence&);
ProcPatt (const Asset::Ident&, const InstructionSequence&);
protected:
explicit ProcPatt (const Asset::Ident& idi);
@ -67,11 +67,11 @@ namespace asset {
ProcPatt& attach (Symbol where, PProc& node);
ProcPatt& operator+= (PProcPatt& toReuse);
};
} // namespace asset
#endif

View file

@ -86,7 +86,7 @@ namespace asset {
, public lib::AutoRegistered<Sequence>
{
typedef mobject::session::RTrack RTrack;
Sequence (Ident const&); //////////////////////////////////////////////TICKET #692 pass in track here
public:
@ -100,7 +100,7 @@ namespace asset {
typedef P<Sequence> PSequence;
///////////////////////////TODO currently just fleshing the API

View file

@ -56,6 +56,7 @@
#include "lib/util.hpp"
#include <boost/format.hpp>
#include <cstdlib>
using boost::format;
@ -80,7 +81,13 @@ namespace asset {
namespace {
Symbol genericIdSymbol ("id");
Symbol seqNrPredicate ("ord");
inline uint
asNumber (string const& spec)
{
return abs(std::atoi (spec.c_str()));
} // returns 0 in case of unparseable number
}
@ -116,6 +123,11 @@ namespace asset {
}
ENSURE (!isnil (nameID));
// does the query actually demand the Nth instance/element?
string seqID = extractID (seqNrPredicate, query);
if (!isnil (seqID) && 1 < asNumber(seqID))
nameID += "."+seqID;
Category cat (STRUCT, StructTraits<STRU>::catFolder());
return Asset::Ident (nameID, cat );
}

View file

@ -87,12 +87,12 @@ namespace asset {
class ID<Struct> : public ID<Asset>
{
public:
ID (size_t id);
ID (HashVal id);
ID (const Struct&);
};
/**
* key abstraction: structural asset
* Created automatically as a sideeffect of building the structure
@ -125,7 +125,7 @@ namespace asset {
// definition of ID<Struct> ctors is possible now,
// after providing full definition of class Struct
inline ID<Struct>::ID(size_t id) : ID<Asset> (id) {};
inline ID<Struct>::ID(HashVal id) : ID<Asset> (id) {};
inline ID<Struct>::ID(const Struct& stru) : ID<Asset> (stru.getID()) {};

View file

@ -27,8 +27,9 @@
using boost::format;
namespace asset
{
namespace asset {
LUMIERA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media referred by placeholder not found");
@ -60,8 +61,6 @@ namespace asset
);
}
LUMIERA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media referred by placeholder not found");
} // namespace asset

View file

@ -28,12 +28,11 @@
namespace asset
{
namespace asset {
const lumiera::Time DUMMY_TIME (25); ///< @todo solve config management
/**
* Placeholder Asset for unknown or unavailable media source.
* @todo maybe do special handling of the media length, allowing
@ -50,11 +49,11 @@ namespace asset
virtual Media::PMedia getOrg() throw(lumiera::error::Invalid);
};
LUMIERA_ERROR_DECLARE (ORIG_NOT_FOUND);
} // namespace asset
#endif

View file

@ -245,11 +245,12 @@ namespace asset {
template ID<Asset> AssetManager::reg (Asset* obj, const Asset::Ident& idi);
template P<Asset> AssetManager::getAsset (const ID<Asset>& id) throw(lumiera::error::Invalid);
template P<Media> AssetManager::getAsset (const ID<Media>& id) throw(lumiera::error::Invalid);
template P<Proc> AssetManager::getAsset (const ID<Proc>& id) throw(lumiera::error::Invalid);
template P<Struct> AssetManager::getAsset (const ID<Struct>& id) throw(lumiera::error::Invalid);
template P<Meta> AssetManager::getAsset (const ID<Meta>& id) throw(lumiera::error::Invalid);
template P<Asset> AssetManager::getAsset (const ID<Asset>& id);
template P<Media> AssetManager::getAsset (const ID<Media>& id);
template P<Proc> AssetManager::getAsset (const ID<Proc>& id);
template P<Struct> AssetManager::getAsset (const ID<Struct>& id);
template P<Meta> AssetManager::getAsset (const ID<Meta>& id);
template P<Pipe> AssetManager::getAsset (const ID<Pipe>& id);
template P<Asset> AssetManager::wrap (const Asset& asset);
template P<Media> AssetManager::wrap (const Media& asset);

View file

@ -0,0 +1,196 @@
/*
OutputDesignation - specifying a desired output destination
Copyright (C) Lumiera.org
2010, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
/** @file output-designation.cpp
** Implementation details of OutputDesignation and OutputMapping.
** Both of these are mostly intended as interface elements to represent
** the intention to connect to another MObject, or a translation and mapping
** of such connection intentions. But parts of the implementation are kept
** here in a translation unit separate of the usage site: The implementation
** of the various kinds of OutputDesignation spec (absolute, indirect, relative)
** and the connection between OutputMapping and the rules based system.
**
** @see OutputDesignation
** @see OutputMapping
** @see OutputMapping_test
**
*/
#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "proc/mobject/mobject.hpp"
#include "proc/mobject/placement-ref.hpp"
#include "proc/mobject/output-designation.hpp"
#include "proc/mobject/output-mapping.hpp"
#include "common/configrules.hpp"
#include <boost/functional/hash.hpp>
#include <cstdlib>
using lumiera::query::QueryHandler;
using lumiera::query::removeTerm;
using lumiera::query::extractID;
using lumiera::ConfigRules;
using lumiera::Symbol;
namespace mobject {
typedef OutputDesignation::PPipe PPipe;
typedef OutputDesignation::PID PID;
typedef OutputDesignation::TargetSpec TargetSpec;
struct AbsoluteSpec
: TargetSpec
{
PID target_;
AbsoluteSpec (PID explicitTarget)
: target_(explicitTarget)
{ }
PID resolve (PPipe) { return target_; }
};
struct IndirectSpec
: TargetSpec
{
RefPlacement mediator_;
IndirectSpec (RefPlacement const& indirectTarget)
: mediator_(indirectTarget)
{ }
PID
resolve (PPipe)
{
REQUIRE (mediator_);
UNIMPLEMENTED ("how to query a placement for output designation");
}
};
struct RelativeSpec
: TargetSpec
{
uint busNr_;
RelativeSpec (uint relative_busNr)
: busNr_(relative_busNr)
{ }
PID
resolve (PPipe)
{
UNIMPLEMENTED ("how the hell can we get a grip on the target to resolve the bus??");
}
};
OutputDesignation::TargetSpec::~TargetSpec() { }
/** create an output designation by directly
* specifying the target to connect
*/
OutputDesignation::OutputDesignation (PID explicitTarget)
: spec_(AbsoluteSpec (explicitTarget))
{ }
/** create an output designation indirectly
* to be resolved by forwarding the resolution
* to the given reference scope / mediator.
*/
OutputDesignation::OutputDesignation (RefPlacement const& indirectTarget)
: spec_(IndirectSpec (indirectTarget))
{ }
/** create an output designation by relative specification,
* to be resolved based on the stream type and the actual
* default target object at hand when resolving.
* @param relative_busNr within the collection of target pipes
* available for the actual stream type to connect
* @note as the relative bus/pipe number defaults to 0,
* effectively this becomes a default ctor, denoting
* "connect me to the first bus suitable for my stream type"
*/
OutputDesignation::OutputDesignation (uint relative_busNr)
: spec_(RelativeSpec (relative_busNr))
{ }
namespace _mapping {
/** @internal to allow for the use of queries mixed with normal Pipe-IDs
* in a single table, we rely on the \c hash_value() function, to be
* picked up by ADL */
HashVal
slot (Query<asset::Pipe> const& query)
{
return hash_value (query);
}
/** @param Query for pipe, which is handed over as-is to the rules engine.
* @return key for a table slot to hold the associated mapping. This slot
* is assumed to contain the mapped Pipe-ID for the given
* query -- including the possibility of a zero hash
* to signal an \em unconnected mapping. */
HashVal
resolveQuery (Query<asset::Pipe> const& query4pipe)
{
PPipe res;
QueryHandler<asset::Pipe>& typeHandler = ConfigRules::instance();
typeHandler.resolve (res, query4pipe);
HashVal resulting_targetPipeID (res? (HashVal)res->getID() : 0 );
return resulting_targetPipeID;
}
Symbol SEQNR_PREDICATE = "ord";
uint
is_defaults_query_with_channel (Query<asset::Pipe> const& query4pipe)
{
string seqNr = extractID (SEQNR_PREDICATE, query4pipe);
return abs(std::atoi (seqNr.c_str())); // also 0 in case of an invalid number
}
Query<asset::Pipe>
build_corresponding_sourceQuery (Query<asset::Pipe> const& query4pipe)
{
Query<asset::Pipe> srcQuery = query4pipe;
removeTerm (SEQNR_PREDICATE, srcQuery);
return srcQuery;
}
}
} // namespace mobject

View file

@ -0,0 +1,116 @@
/*
OUTPUT-DESIGNATION.hpp - specifying a desired output destination
Copyright (C) Lumiera.org
2010, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef PROC_MOBJECT_OUTPUT_DESIGNATION_H
#define PROC_MOBJECT_OUTPUT_DESIGNATION_H
#include "proc/asset/pipe.hpp"
#include "lib/opaque-holder.hpp"
#include "lib/meta/typelist-util.hpp"
extern "C" {
#include "lib/luid.h"
}
namespace mobject {
class MObject;
template<class MX>
class PlacementRef;
typedef PlacementRef<MObject> RefPlacement;
/**
* Descriptor to denote the desired target of produced media data.
* OutputDesignation is always an internal and relative specification
* and boils down to referring an asset::Pipe by ID. In order to get
* actually effective, some object within the model additionally
* needs to \em claim this pipe-ID, meaning that this object
* states to root and represent this pipe. When the builder
* encounters a pair of (OutputDesignation, OutputClaim),
* an actual stream connection will be wired in the
* processing node network.
*
* @todo couldn't the inline buffer be "downgraded" to InPlaceBuffer ??
* Seemingly we never-ever need to re-discover the erased type of the embedded spec.
* Thus for this to work, we'd just need to add an "empty" spec ///////////////////TICKET #723
*/
class OutputDesignation
{
public:
typedef asset::ID<asset::Pipe> PID;
typedef asset::PPipe PPipe;
explicit OutputDesignation (PID explicitTarget);
explicit OutputDesignation (RefPlacement const& indirectTarget);
explicit OutputDesignation (uint relative_busNr =0);
// using default copying
/** retrieve the direct destination
* this descriptor is actually pointing to.
* In case of a target pipe not explicitly specified
* this might involve a resolution step and take the
* current context into account.
* @param origin starting point for figuring out connections
* @return a pipe-ID, which should be used as next connection.
* This might not be the final designation, but the
* directly visible next pipe to connect to
*/
PID
resolve (PPipe origin)
{
return spec_->resolve (origin);
}
//TODO: API to retrieve target stream type
class TargetSpec
{
public:
virtual ~TargetSpec();
virtual PID resolve (PPipe origin) =0;
};
private:
enum {
SPEC_SIZ = lumiera::typelist::maxSize<
lumiera::typelist::Types<PID,lumiera_uid,uint>::List>::value
};
typedef lib::OpaqueHolder<TargetSpec, SPEC_SIZ> SpecBuff;
/** Storage to hold the Target Spec inline */
SpecBuff spec_;
};
} // namespace mobject
#endif

View file

@ -0,0 +1,404 @@
/*
OUTPUT-MAPPING.hpp - generic interface for translation of output designations
Copyright (C) Lumiera.org
2010, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file output-mapping.hpp
** Translating and wiring output designations.
** OutputMapping is a complement to the OutputDesignation handles
** used at various places in the high-level model. It is used when
** translating a given output spec into another connection target
** - when connecting an model port to a concrete external output
** - when connecting a timeline to a viewer element
** - for implementing the viewer input selection "switchbord"
** - for translating output designation of virtual clips
** OutputMapping is to be used as value object, holding concrete
** connections and wiring. For each of the mentioned usage situations,
** it needs to be adapted specifically, which is achieved by template
** (generic) programming: The usage situation provides a definition
** context DEF to fill in the variable parts of the implementation.
** This definition context is actually instantiated (as base class).
** The mapping table actually just stores an association of hash
** values, which typically are interpreted as asset::ID<Pipe>.
** But the actual mapping result is retrieved on each acces
** by invoking a functor on the stored hash value,
** thus the final resolution is done \em late.
**
** @see OutputDesignation
** @see OutputMapping_test
**
*/
#ifndef PROC_MOBJECT_OUTPUT_MAPPING_H
#define PROC_MOBJECT_OUTPUT_MAPPING_H
#include "proc/asset/pipe.hpp"
#include "lib/bool-checkable.hpp"
#include "lib/error.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp"
#include <boost/operators.hpp>
#include <map>
namespace mobject {
namespace { // Helper to extract and rebind definition types
/**
* @internal used by OutputMapping
* to figure out the mapping target type
*/
template<class DEF>
class _def
{
typedef asset::ID<asset::Pipe> PId;
template<typename FUN>
struct Rebind;
template<typename RET>
struct Rebind<RET(DEF::*)(PId)>
{
typedef RET Res;
};
typedef typeof(&DEF::output) OutputMappingMemberFunc; // GCC extension: "typeof"
typedef Rebind<OutputMappingMemberFunc> Rebinder;
public:
typedef typename Rebinder::Res Target;
};
}//(End) type rebinding helper
namespace error = lumiera::error;
using lumiera::Query;
using asset::HashVal;
/**
* OutputMapping is a facility to resolve output designations.
* For a given specification, resolution to the desired
* target specification may be derived. Here, the
* type of the target specification is defined
* through the type parameter.
*
* \par definition of specific mapping behaviour
*
* This is an generic map-like container, acting as Interface to be used
* in the signature of API functions either providing or requiring a Mapping.
* For each distinct usage situation, an instantiation of this template should
* be created, providing a <i>definition context</i> as template parameter.
* Instances of this concrete mapping type may then be default constructed
* and copied freely. The definition context is supposed to provide
* - a functor \c DEF::output usable as function pipe-ID --> Target
* - the concrete output-functor also defines the concrete Target type,
* which will be returned when accessing the OutputMapping
* - a function \c DEF::buildQuery(sourcePipeID,seqNr) yielding a (defaults)
* query to be issued in case of accessing a non existent mapping
*/
template<class DEF>
class OutputMapping
: public DEF
{
typedef _def<DEF> Setup;
typedef asset::ID<asset::Pipe> PId;
typedef asset::PPipe PPipe;
/* == mapping table storage == */
std::map<HashVal,HashVal> table_;
public:
typedef typename Setup::Target Target;
// using default ctor and copy operations
size_t size() const { return table_.size(); }
bool empty() const { return 0 == size(); }
void clear() { table_.clear(); }
/**
* @internal transient resolution wrapper to be exposed by map-style access.
* A Resolver instance represents an output mapping result, yet to be fully resolved.
* It is created on the stack by the OutputMapping container and internally wired
* back to the container and the actually stored value (pipe-ID-hash) in the table.
* Actually retrieving the result value by the client code triggers invocation
* of the specific resolution functor, embedded in the definition context DEF,
* which was given when instantiating the OutputMapping template.
* @note depends on the template parameter of the enclosing OutputMapping type!
*/
class Resolver
: public lib::BoolCheckable<Resolver // bool conversion to signal "unconnected"...
, boost::equality_comparable<Resolver, Target, // final mapping result can be compared to Target...
boost::equality_comparable<Resolver> // mapping values can be compared.
> > //
{
OutputMapping& thisMapping_;
HashVal& pID_;
Resolver (OutputMapping& container, HashVal& resultVal)
: thisMapping_(container)
, pID_(resultVal)
{ }
friend class OutputMapping;
/* copy by clients prohibited */
Resolver& operator= (Resolver const&);
Target
resolve() const
{
REQUIRE (pID_);
PId targetPipeID (pID_);
return thisMapping_.resolveTarget (targetPipeID);
}
public:
/** explicitly define a new target ID for this individual mapping
* @note the actually returned result depends on what the configured
* \c DEF::output functor will yield when invoked on this ID
*/
void
operator= (PId newId2map)
{
pID_ = newId2map;
}
void
operator= (PPipe newPipe2map)
{
REQUIRE (newPipe2map);
pID_ = newPipe2map->getID();
}
void
disconnect() ///< switch this individual mapping into \em unconnected state
{
pID_ = 0;
}
/** actually retrieve the target object of the mapping.
* This operation is invoked when client code accesses
* the result of an OutputMapping query.
* @return result of invoking the configured \c DEF::output functor
* @throw error::Logic when resoving an \em unconnected mapping
*/
operator Target()
{
if (!isValid())
throw error::Logic ("attempt to resolve an unconnected output mapping"
, error::LUMIERA_ERROR_UNCONNECTED);
return resolve();
}
bool
isValid() const ///< is this a valid \em connected mapping?
{
return bool(pID_);
}
/* === equality comparisons (boost::operators) === */
friend bool
operator== (Resolver const& a, Resolver const& b)
{
return a.pID_ == b.pID_;
} // note: Resolver depends on template parameter DEF
// All instances of DEF are considered equivalent!
friend bool
operator== (Resolver const& rr, Target const& tval)
{
return rr.resolve() == tval;
}
};
/* === Map-style access for clients === */
Resolver operator[] (PId sourcePipeID);
Resolver operator[] (PPipe const& pipe);
Resolver operator[] (Query<asset::Pipe> query4pipe);
bool
contains (PId mapping4sourcePipeID)
{
return util::contains (table_, mapping4sourcePipeID);
}
bool
contains (PPipe sourcePipe)
{
return !sourcePipe
|| this->contains (sourcePipe->getID());
}
private:
Target
resolveTarget (PId mappedPipeID)
{
return DEF::output (mappedPipeID);
}
Resolver
buildResolutionWrapper (HashVal tableSlot)
{
ASSERT (this->contains (tableSlot));
return Resolver (*this, table_[tableSlot]);
}
};
/* ===== Implementation details ===== */
namespace _mapping {
/** yield a suitable table slot for this query */
HashVal slot (Query<asset::Pipe> const&);
/** delegate target pipe resolution to the rules system */
HashVal resolveQuery (Query<asset::Pipe> const&);
/** detect the special case, when actually the Nth
* solution of a defaults query is requested */
uint is_defaults_query_with_channel (Query<asset::Pipe> const&);
/** ..and build the corresponding defaults source query for this case */
Query<asset::Pipe> build_corresponding_sourceQuery (Query<asset::Pipe> const&);
}
/** standard map-style access to an OutputMapping.
* For the given source pipe-ID the mapped target pipe-ID is fetched
* and then handed over to the configured \c DEF::output functor, which
* is assumed to calculate or retrieve the actual result object.
*
* \par default mappings
* whenever accessing an yet non-existent mapping, a query is issued
* behind the scenes to establish a suitable default mapping. The actual
* query is built from a query template by the \c DEF::buildQuery function
* and thus can be configured for the concrete usage situation of the mapping.
* @warning depending on the actually configured defaults query, there might be
* no solution, in which case an \em unconnected marker is retrieved and
* stored. Thus the yielded Resolver should be checked, if in doubt.
*/
template<class DEF>
inline typename OutputMapping<DEF>::Resolver
OutputMapping<DEF>::operator[] (PId sourcePipeID)
{
if (!contains (sourcePipeID))
{
// issue a defaults query to resolve this mapping first
Query<asset::Pipe> query4pipe = DEF::buildQuery (sourcePipeID);
table_[sourcePipeID] = _mapping::resolveQuery (query4pipe);
}
return buildResolutionWrapper (sourcePipeID);
}
/** similar to the standard map-style access, but accepts
* a source pipe object instead of just a pipe-ID */
template<class DEF>
inline typename OutputMapping<DEF>::Resolver
OutputMapping<DEF>::operator[] (PPipe const& pipe)
{
REQUIRE (pipe);
return (*this) [pipe->getID()];
}
/** determine an OutputMapping by resolving a complex query,
* instead of just picking a mapped pipe (which is the default usage).
* Accessing the OutputMapping this way by query enables all kinds of
* extended usages: It suffices that the given query somehow yields a Pipe,
* which then is considered the mapped result and handed over to the \c DEF::output
* functor for resolution to a result object to be returned.
*
* \par Query for the Nth default instance
* OutputMapping provides a special behaviour for retrieving "the Nth default pipe".
* The rationale being the request for connection to the Nth bus of a given kind, like
* e.g. the 3rd audio subgroup or the 2nd video master. This special behaviour is triggered
* by the predicate "ord(##)" in the query. The \em remainder of the query is supposed to
* designate a \em default in this case, rather then querying directly for the result of
* the mapping. Thus this remainder of the query is used to retrieve a \em source pipe,
* which then is treated as if accessing a non-existent mapping: a suitable default
* solution for this mapping is retrieved, but in this special case, we append the
* given sequence number to the ID of the retrieved pipe, i.e. we get the Nth
* (identical) solution to the aforementioned query for a default pipe.
*
* @note the mapped result is remembered within this mapping. Further invocations
* with the \em same query will just fetch this stored pipe-ID and hand it
* to the functor, without resolving the query again. You might want to
* \link Resolver::disconnect remove \endlink this specific mapping
* in order to force re-evaluation of the query.
* @param Query for a pipe, which is handed over as-is to the rules engine.
* @warning depending on the actual query, there might be no solution,
* in which case an \em unconnected marker is retrieved and
* stored. Thus the yielded Resolver should be checked,
* if in doubt.
*/
template<class DEF>
inline typename OutputMapping<DEF>::Resolver
OutputMapping<DEF>::operator[] (Query<asset::Pipe> query4pipe)
{
HashVal hash4query = _mapping::slot (query4pipe);
if (!contains (hash4query))
{
if (uint seqNr = _mapping::is_defaults_query_with_channel (query4pipe))
{
// treat the special case
// when actually requesting the "Nth default of this kind"
PPipe corresponding_sourcePipe
= asset::Pipe::query(
_mapping::build_corresponding_sourceQuery (query4pipe));
ENSURE (corresponding_sourcePipe);
PId sourcePipeID = corresponding_sourcePipe->getID();
query4pipe = DEF::buildQuery (sourcePipeID, seqNr);
}
// need to resolve this query first
table_[hash4query] = _mapping::resolveQuery (query4pipe);
}
ENSURE (this->contains (hash4query));
return buildResolutionWrapper (hash4query);
}
} // namespace mobject
#endif

View file

@ -21,19 +21,20 @@
* *****************************************************/
#include "lib/error.hpp"
#include "proc/mobject/parameter.hpp"
#include "proc/mobject/paramprovider.hpp"
namespace mobject
{
namespace mobject {
template<class VAL>
VAL
Parameter<VAL>::getValue ()
{
////////////TODO
UNIMPLEMENTED ("Any idea how to handle various kinds of parameter types");
}
} // namespace mobject

View file

@ -21,18 +21,17 @@
*/
#ifndef MOBJECT_PARAMETER_H
#define MOBJECT_PARAMETER_H
#ifndef PROC_MOBJECT_PARAMETER_H
#define PROC_MOBJECT_PARAMETER_H
namespace mobject
{
namespace mobject {
template<class VAL> class ParamProvider;
/**
* Descriptor and access object for a plugin parameter.
* Parameters may be provided with values from the session,
@ -43,13 +42,13 @@ namespace mobject
{
public:
VAL getValue () ;
protected:
ParamProvider<VAL>* provider;
};
} // namespace mobject
#endif

View file

@ -0,0 +1,50 @@
/*
BusMO - attachment point to form a global pipe
Copyright (C) Lumiera.org
2010, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "proc/mobject/session/bus-mo.hpp"
namespace mobject {
namespace session {
/** */
BusMO::BusMO (PPipe const& pipe_to_represent)
: pipe_(pipe_to_represent)
{
throwIfInvalid();
TODO ("what additionally to do when rooting a global pipe??");
}
bool
BusMO::isValid() const
{
TODO ("self-check of a global pipe within the model"); ///////////////////////////////TICKET #584
return true;
// Ideas: - maybe re-access the pipe "from outward"
// - and then verify matching WiringClaim in the corresponding placement
}
}} // namespace mobject::session

View file

@ -0,0 +1,75 @@
/*
BUS-MO.hpp - attachment point to form a global pipe
Copyright (C) Lumiera.org
2010, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef MOBJECT_SESSION_BUS_MO_H
#define MOBJECT_SESSION_BUS_MO_H
#include "proc/mobject/session/meta.hpp"
#include "proc/mobject/builder/buildertool.hpp"
namespace asset {
class Pipe;
typedef lumiera::P<Pipe> PPipe;
}
namespace mobject {
namespace session {
using asset::PPipe;
/**
* Model entity corresponding to a global pipe.
* This MObject acts as scope and attachment point to form a global pipe.
* Each Timeline (implemented as Binding-MObject) holds a collection of
* such global pipes, which then in turn may be nested.
*/
class BusMO : public Meta
{
PPipe pipe_;
string
initShortID() const
{
return buildShortID("Bus");
}
bool isValid() const;
public:
BusMO (PPipe const& pipe_to_represent);
DEFINE_PROCESSABLE_BY (builder::BuilderTool);
};
} // namespace mobject::session
/** Placement<BusMO> defined to be subclass of Placement<Meta> */
template class Placement<session::BusMO, session::Meta>;
typedef Placement<session::BusMO, session::Meta> PBus;
} // namespace mobject
#endif

View file

@ -15,3 +15,7 @@ PLANNED "BuildSegment_test" BuildSegment_test <<END
END
TEST "Output pipe mapping" OutputMapping_test <<END
return: 0
END

View file

@ -76,6 +76,7 @@ test_components_SOURCES = \
$(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \
$(testcomponents_srcdir)/proc/mobject/mobject-interface-test.cpp \
$(testcomponents_srcdir)/proc/mobject/mobject-ref-test.cpp \
$(testcomponents_srcdir)/proc/mobject/output-mapping-test.cpp \
$(testcomponents_srcdir)/proc/mobject/placement-basic-test.cpp \
$(testcomponents_srcdir)/proc/mobject/placement-hierarchy-test.cpp \
$(testcomponents_srcdir)/proc/mobject/placement-object-identity-test.cpp \

View file

@ -0,0 +1,182 @@
/*
OutputMapping(Test) - verify generic output designation mapping
Copyright (C) Lumiera.org
2010, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "proc/mobject/output-mapping.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/util.hpp"
#include <boost/format.hpp>
#include <string>
using boost::format;
using util::isnil;
using std::string;
namespace mobject {
namespace test {
using asset::Pipe;
using asset::PPipe;
typedef asset::ID<Pipe> PID;
/*********************************************************************************
* @test create a synthetic / example mapping to verify generic mapping behaviour.
* We're creating a custom mapping type here, for this test only: The
* struct DummyDef provides a "definition context" for this custom mapping
* - there is a function to retrieve the actual target object
* for any target pipe stored in the mapping. In this case,
* we just extract the name-ID string from the pipe as result
* - as an additional sideeffect, this DummyDef::output functor
* also defines the Target type of this custom mapping to be std::string
* - DummyDef::buildQuery provides a template query, to be issued whenever
* a yet nonexistent mapping is requested. In this special case here
* we query for a pipe with the name "master_XXX", where XXX denotes
* the stream-type of the source pipe to be mapped.
*
* @see mobject::OutputDesignation
* @see mobject::session::Binding
*/
class OutputMapping_test : public Test
{
struct DummyDef
{
string
output (PID target)
{
return Pipe::lookup(target)->ident.name;
}
Query<Pipe>
buildQuery (PID sourcePipeID, uint seqNr =0)
{
PPipe srcP = Pipe::lookup (sourcePipeID);
format queryPattern ("id(master_%1%), stream(%1%), ord(%2%)");
return Query<Pipe> (queryPattern % srcP->getStreamID() % seqNr);
}
};
typedef OutputMapping<DummyDef> Mapping;
virtual void
run (Arg)
{
map_and_retrieve();
instance_copy();
default_mapping();
}
void
map_and_retrieve()
{
Mapping map;
CHECK (isnil (map));
PPipe p1 = Pipe::query("id(hairy)");
PPipe p2 = Pipe::query("id(furry)");
PPipe pX = Pipe::query("id(curly)");
map[p1] = p2;
CHECK (!isnil (map));
CHECK (1 == map.size());
CHECK (map[p1] == "furry");
CHECK (map[p1].isValid());
CHECK (map[p1]);
CHECK (!map.contains (pX));
CHECK (!map.contains (p2));
// create an unconnected mapping
map[pX].disconnect();
CHECK (map.contains (pX));
CHECK (!map[pX].isValid());
CHECK (!map[pX]);
}
void
instance_copy()
{
Mapping m1;
PPipe p1 = Pipe::query("id(hairy)");
PPipe p2 = Pipe::query("id(furry)");
PPipe pi = Pipe::query("id(nappy)");
m1[pi] = p1;
Mapping m2(m1);
CHECK (!isnil (m2));
CHECK (1 == m2.size());
CHECK (m1[pi] == "hairy");
CHECK (m2[pi] == "hairy");
m1[pi] = p2;
CHECK (m1[pi] == "furry");
CHECK (m2[pi] == "hairy");
m2 = m1;
CHECK (m1[pi] == "furry");
CHECK (m2[pi] == "furry");
m1.clear();
CHECK (isnil(m1));
CHECK (!isnil(m2));
CHECK (m2[pi] == "furry");
CHECK (!m1.contains (pi));
}
void
default_mapping()
{
Mapping map;
CHECK (isnil (map));
PPipe p1 = Pipe::query("stream(hairy)");
PPipe p2 = Pipe::query("stream(furry)");
CHECK (map[p1] == "master_hairy");
CHECK (map[p2] == "master_furry");
// create new mapping to an explicitly queried target
Query<Pipe> some_pipe ("pipe(super_curly)");
CHECK (map[some_pipe] == "super_curly");
// create a new mapping to the 2nd master for "furry" data
Query<Pipe> special_bus ("stream(furry), ord(2)");
CHECK (map[special_bus] == "master_furry.2");
}
};
/** Register this test class... */
LAUNCHER (OutputMapping_test, "unit session builder");
}} // namespace mobject::test

View file

@ -1,6 +1,6 @@
format 58
"Asset" // ProcessingLayer::Asset
revision 21
revision 22
modified_by 5 "hiv"
// class settings
//class diagram settings
@ -741,6 +741,14 @@ ${inlines}
classrelation_ref 195717 // <generalisation>
b parent class_ref 136965 // Struct
end
classrelation 204549 // <dependency>
relation 193669 -_->
a default
cpp default "#include in source"
classrelation_ref 204549 // <dependency>
b parent class_ref 128389 // Track
end
end
class 160901 "Timeline"

View file

@ -112,6 +112,8 @@ classcanvas 148613 class_ref 152453 // PlacementRef
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 685 342 2005
end
textcanvas 151301 "note: this is a simplified / conceptual view"
xyzwh 217 657 2000 191 13
relationcanvas 128389 relation_ref 128005 // <directional composition>
from ref 128005 z 1999 to ref 128133
role_a_pos 171 615 3000 no_role_b
@ -122,13 +124,6 @@ relationcanvas 128517 relation_ref 128133 // <unidirectional association>
role_a_pos 237 811 3000 no_role_b
multiplicity_a_pos 211 811 3000 no_multiplicity_b
end
relationcanvas 128645 relation_ref 128261 // <generalisation>
geometry VHr
from ref 128261 z 1999 to point 253 859
line 128901 z 1999 to ref 128133
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 130821 relation_ref 128517 // <directional aggregation>
geometry VH
from ref 128133 z 1999 stereotype "<<list>>" xyz 257 587 3000 to point 253 95
@ -168,7 +163,7 @@ relationcanvas 134533 relation_ref 130309 // <generalisation>
end
relationcanvas 135941 relation_ref 131077 // <directional composition>
from ref 128261 z 1999 stereotype "<<list>>" xyz 578 844 3000 to ref 135813
role_a_pos 642 844 3000 no_role_b
role_a_pos 641 843 3000 no_role_b
multiplicity_a_pos 714 866 3000 no_multiplicity_b
end
relationcanvas 136709 relation_ref 131333 // <generalisation>
@ -240,7 +235,7 @@ relationcanvas 144517 relation_ref 143877 // <unidirectional association>
from ref 141317 z 1999 to point 499 150
line 144645 z 1999 to point 499 180
line 144773 z 1999 to ref 141317
role_a_pos 498 156 3000 no_role_b
role_a_pos 504 161 3000 no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 144901 relation_ref 144901 // <generalisation>
@ -263,7 +258,7 @@ relationcanvas 146565 relation_ref 145669 // <generalisation>
end
relationcanvas 146693 relation_ref 145797 // <unidirectional association>
from ref 146437 z 1999 to ref 146053
role_a_pos 408 527 3000 no_role_b
role_a_pos 400 525 3000 no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 147077 relation_ref 155653 // <directional composition>
@ -307,9 +302,9 @@ relationcanvas 150149 relation_ref 184581 // <unidirectional association>
no_multiplicity_a no_multiplicity_b
end
relationcanvas 150277 relation_ref 184709 // <directional composition>
from ref 128005 z 1999 to point 137 602
from ref 128005 z 1999 to point 137 608
line 150405 z 1999 to ref 146949
role_a_pos 171 567 3000 no_role_b
role_a_pos 172 567 3000 no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 151045 relation_ref 142853 // <unidirectional association>

View file

@ -1,6 +1,6 @@
format 58
"RenderEngine" // ProcessingLayer::RenderEngine
revision 19
revision 20
modified_by 5 "hiv"
// class settings
//class diagram settings
@ -311,28 +311,6 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl}
end
end
class 131845 "Trafo"
visibility package
cpp_decl "${comment}${template}class ${name}${inherit}
{
${members} };
${inlines}
"
java_decl ""
php_decl ""
python_2_2 python_decl ""
idl_decl ""
explicit_switch_type ""
classrelation 132997 // <generalisation>
relation 132229 ---|>
a public
cpp default "${type}"
classrelation_ref 132997 // <generalisation>
b parent class_ref 131717 // ProcNode
end
end
class 131973 "Link"
visibility package
cpp_decl "${comment}${template}class ${name}${inherit}
@ -369,13 +347,6 @@ ${inlines}
explicit_switch_type ""
comment "Special video processing node used to scale and translate image data."
classrelation 133509 // <generalisation>
relation 132741 ---|>
a public
cpp default "${type}"
classrelation_ref 133509 // <generalisation>
b parent class_ref 131845 // Trafo
end
end
class 132357 "Mask"
@ -391,13 +362,6 @@ ${inlines}
idl_decl ""
explicit_switch_type ""
classrelation 133637 // <generalisation>
relation 132869 ---|>
a public
cpp default "${type}"
classrelation_ref 133637 // <generalisation>
b parent class_ref 131845 // Trafo
end
end
class 132485 "PluginAdapter"
@ -414,56 +378,6 @@ ${inlines}
explicit_switch_type ""
comment "Adapter used to integrage an effects processor in the render pipeline"
classrelation 133765 // <generalisation>
relation 132997 ---|>
a public
cpp default "${type}"
classrelation_ref 133765 // <generalisation>
b parent class_ref 131845 // Trafo
end
end
class 135045 "CodecAdapter"
visibility package
cpp_decl "${comment}${template}class ${name}${inherit}
{
${members} };
${inlines}
"
java_decl ""
php_decl ""
python_2_2 python_decl ""
idl_decl ""
explicit_switch_type ""
classrelation 138757 // <generalisation>
relation 136965 ---|>
a public
cpp default "${type}"
classrelation_ref 138757 // <generalisation>
b parent class_ref 131845 // Trafo
end
end
class 133253 "Frame"
abstract visibility public stereotype "interface"
cpp_decl "${comment}${template}class ${name}${inherit}
{
${members} };
${inlines}
"
java_decl "${comment}${@}${visibility}interface ${name}${extends} {
${members}}
"
php_decl ""
python_2_2 python_decl ""
idl_decl "${comment}${abstract}${local}interface ${name}${inherit} {
${members}};
"
explicit_switch_type ""
comment "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"
end
class 133381 "AFrame"
@ -479,13 +393,6 @@ ${inlines}
idl_decl ""
explicit_switch_type ""
classrelation 135045 // <generalisation>
relation 133893 ---|>
a public
cpp default "${type}"
classrelation_ref 135045 // <generalisation>
b parent class_ref 133253 // Frame
end
end
class 133509 "VFrame"
@ -501,13 +408,6 @@ ${inlines}
idl_decl ""
explicit_switch_type ""
classrelation 135173 // <generalisation>
relation 134021 ---|>
a public
cpp default "${type}"
classrelation_ref 135173 // <generalisation>
b parent class_ref 133253 // Frame
end
end
class 133637 "GLBuf"
@ -523,13 +423,6 @@ ${inlines}
idl_decl ""
explicit_switch_type ""
classrelation 135301 // <generalisation>
relation 134149 ---|>
a public
cpp default "${type}"
classrelation_ref 135301 // <generalisation>
b parent class_ref 133253 // Frame
end
end
class 133765 "Source"
@ -632,14 +525,6 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl}
b parent class_ref 142469 // StateProxy
end
classrelation 152837 // <unidirectional association>
relation 149381 --->
a role_name "" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 152837 // <unidirectional association>
b parent class_ref 133253 // Frame
end
end
class 142725 "WiringDescriptor"

View file

@ -1,6 +1,6 @@
format 58
"CommonLib" // CommonLib
revision 19
revision 20
modified_by 5 "hiv"
// class settings
//class diagram settings

View file

@ -1,6 +1,6 @@
format 58
"Builder" // ProcessingLayer::MObject::Builder
revision 19
revision 20
modified_by 5 "hiv"
// class settings
//class diagram settings
@ -331,16 +331,6 @@ ${members}};
"
explicit_switch_type ""
classrelation 135941 // currFrame (<unidirectional association>)
relation 134533 --->
stereotype "vector"
a role_name "currFrame" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value};
"
classrelation_ref 135941 // currFrame (<unidirectional association>)
b multiplicity "1" parent class_ref 133253 // Frame
end
operation 135813 "fetch"
public explicit_return_type ""
nparams 0

View file

@ -1,30 +1,30 @@
format 40
format 58
"proc" // design::codegen::proc
revision 8
revision 9
modified_by 5 "hiv"
// class settings
//class diagram settings
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
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
//use case diagram settings
package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
package_name_in_tab default show_context default auto_label_position default draw_all_relations default class_drawing_mode default shadow default show_stereotype_properties default
//sequence diagram settings
show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default
show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
//collaboration diagram settings
show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default
show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default show_stereotype_properties default
//object diagram settings
write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default
//component diagram settings
package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
draw_component_as_icon default show_component_req_prov default show_component_rea default
draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
//deployment diagram settings
package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default
draw_component_as_icon default show_component_req_prov default show_component_rea default
draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
//state diagram settings
package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default
show_activities default region_horizontally default drawing_language default
show_activities default region_horizontally default drawing_language default show_stereotype_properties default
//activity diagram settings
package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
show_infonote default drawing_language default
show_infonote default drawing_language default show_stereotype_properties default
stereotype "src"
cpp_h_dir "proc"
@ -36,7 +36,7 @@ All classes belonging to the (middle) processing layer"
deploymentview 128517 "gen"
//deployment diagram settings
package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default
draw_component_as_icon default show_component_req_prov default show_component_rea default
draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
comment "defines source files to be generated by BOUML"
artifact 136197 "assetmanager"
stereotype "source"
@ -228,7 +228,6 @@ ${namespace_start}
${members}
${namespace_end}"
associated_classes
class_ref 133253 // Frame
end
comment "Key Abstraction: render process and buffer holding frame data."
end

View file

@ -1,30 +1,30 @@
format 40
format 58
"engine" // design::codegen::proc::engine
revision 10
revision 11
modified_by 5 "hiv"
// class settings
//class diagram settings
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
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
//use case diagram settings
package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
package_name_in_tab default show_context default auto_label_position default draw_all_relations default class_drawing_mode default shadow default show_stereotype_properties default
//sequence diagram settings
show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default
show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
//collaboration diagram settings
show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default
show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default show_stereotype_properties default
//object diagram settings
write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default
//component diagram settings
package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
draw_component_as_icon default show_component_req_prov default show_component_rea default
draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
//deployment diagram settings
package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default
draw_component_as_icon default show_component_req_prov default show_component_rea default
draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
//state diagram settings
package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default
show_activities default region_horizontally default drawing_language default
show_activities default region_horizontally default drawing_language default show_stereotype_properties default
//activity diagram settings
package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
show_infonote default drawing_language default
show_infonote default drawing_language default show_stereotype_properties default
stereotype "src"
cpp_h_dir "proc/engine"
@ -36,7 +36,7 @@ The Core Render Engine"
deploymentview 129285 "gen"
//deployment diagram settings
package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default
draw_component_as_icon default show_component_req_prov default show_component_rea default
draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
comment "defines source files to be generated by BOUML"
artifact 131973 "renderengine"
stereotype "source"
@ -228,7 +228,6 @@ ${namespace_start}
${members}
${namespace_end}"
associated_classes
class_ref 131845 // Trafo
end
comment "transforming processing Node "
end
@ -461,7 +460,6 @@ ${namespace_start}
${members}
${namespace_end}"
associated_classes
class_ref 135045 // CodecAdapter
end
comment "Processing Node for (de)coding media data"
end

View file

@ -32,18 +32,6 @@ classcanvas 130821 class_ref 133765 // Source
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 371 407 2000
end
classcanvas 131077 class_ref 135045 // CodecAdapter
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 309 472 2000
end
classcanvas 131205 class_ref 131845 // Trafo
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 309 407 2000
end
classcanvas 134661 class_ref 133253 // Frame
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 193 472 2000
end
packagecanvas 135685
package_ref 128261 // MObject
xyzwh 24 10 1994 187 356
@ -52,8 +40,8 @@ packagecanvas 135813
package_ref 128133 // Asset
xyzwh 447 9 1994 391 570
end
note 136837 "the Builder implements each Clip by a source node and maybe some codec"
xyzwh 59 390 2000 209 46
note 136837 "the Builder implements each Clip by a chain of nodes, finally leading to a source node"
xyzwh 59 382 2000 227 46
classcanvas 137221 class_ref 138501 // CompoundMedia
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 594 147 3005
@ -106,14 +94,6 @@ relationcanvas 129669 relation_ref 129285 // <generalisation>
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 132357 relation_ref 132229 // <generalisation>
geometry VHV
from ref 131205 z 1999 to point 329 381
line 132485 z 1999 to point 301 381
line 132613 z 1999 to ref 130309
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 132741 relation_ref 135429 // <unidirectional association>
from ref 130309 z 1999 to point 235 278
line 132869 z 1999 to point 235 314
@ -121,11 +101,6 @@ relationcanvas 132741 relation_ref 135429 // <unidirectional association>
role_a_pos 220 299 3000 no_role_b
no_multiplicity_a multiplicity_b_pos 248 306 3000
end
relationcanvas 133125 relation_ref 136965 // <generalisation>
from ref 131077 z 1999 to ref 131205
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 133893 relation_ref 134661 // <generalisation>
geometry VHV
from ref 130821 z 1999 to point 392 381

View file

@ -1,6 +1,6 @@
format 58
"Session" // ProcessingLayer::MObject::Session
revision 3
revision 4
modified_by 5 "hiv"
// class settings
//class diagram settings
@ -143,17 +143,6 @@ ${inlines}
b parent class_ref 139653 // Session
end
classrelation 147717 // pipes (<directional aggregation>)
relation 145541 o-->
stereotype "vector"
a role_name "pipes" multiplicity "*" protected
comment "the global ports (busses) of the session"
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 147717 // pipes (<directional aggregation>)
b parent class_ref 138117 // Pipe
end
classrelation 195205 // timelines (<directional composition>)
relation 184709 *-->
a role_name "timelines" protected
@ -162,6 +151,15 @@ ${inlines}
classrelation_ref 195205 // timelines (<directional composition>)
b parent class_ref 145541 // Timeline
end
classrelation 204677 // <unidirectional association>
relation 193797 --->
a role_name "" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 204677 // <unidirectional association>
b parent class_ref 152069 // PlacementIndex
end
end
class 139781 "SessManager"
@ -321,6 +319,14 @@ ${inlines}
classrelation_ref 195077 // <unidirectional association>
b parent class_ref 128133 // Seq
end
classrelation 204421 // <dependency>
relation 193541 -_->
a default
cpp default "#include in source"
classrelation_ref 204421 // <dependency>
b parent class_ref 152325 // Binding
end
end
class 145797 "TimelineView"
@ -413,14 +419,6 @@ ${inlines}
idl_decl ""
explicit_switch_type ""
classrelation 128517 // <generalisation>
relation 128261 ---|>
a public
cpp default "${type}"
classrelation_ref 128517 // <generalisation>
b parent class_ref 128133 // Seq
end
classrelation 131717 // effectiveTimeline (<directional composition>)
relation 131077 *-->
stereotype "list"
@ -607,18 +605,6 @@ ${inlines}
b parent class_ref 129157 // Meta
end
classrelation 147205 // subTracks (<directional composition>)
relation 145029 *-->
stereotype "vector"
a role_name "subTracks" multiplicity "*" public
comment "Child tracks in a tree structure"
cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value};
"
classrelation_ref 147205 // subTracks (<directional composition>)
b parent class_ref 128389 // Track
association_type class_ref 128645 // Placement
end
classrelation 161413 // <realization>
relation 156805 -_-|>
a public
@ -641,6 +627,46 @@ ${inlines}
idl_decl ""
explicit_switch_type ""
classrelation 204293 // <unidirectional association>
relation 193413 --->
a role_name "" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 204293 // <unidirectional association>
b parent class_ref 152197 // Sequence
end
classrelation 204805 // <directional aggregation>
relation 193925 o-->
a role_name "" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 204805 // <directional aggregation>
b parent class_ref 167429 // BusMO
end
end
class 167429 "BusMO"
visibility package
cpp_decl "${comment}${template}class ${name}${inherit}
{
${members} };
${inlines}
"
java_decl ""
php_decl ""
python_2_2 python_decl ""
idl_decl ""
explicit_switch_type ""
classrelation 204933 // <unidirectional association>
relation 194053 --->
a role_name "" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 204933 // <unidirectional association>
b parent class_ref 138117 // Pipe
end
end
class 128517 "MObject"
@ -821,15 +847,6 @@ ${members}};
idl_decl ""
end
classrelation 131845 // <unidirectional association>
relation 131205 --->
a role_name "" protected
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
"
classrelation_ref 131845 // <unidirectional association>
b parent class_ref 128389 // Track
association_type class_ref 128389 // Track
end
end
class 128773 "AbstractMO"
@ -1623,7 +1640,7 @@ ${inlines}
package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
show_infonote default drawing_language default show_stereotype_properties default
classdiagram 136453 "Session backbone"
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
draw_all_relations no hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
size A4
end

View file

@ -2,18 +2,72 @@ format 58
classcanvas 128005 class_ref 152069 // PlacementIndex
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 484 147 2000
xyz 410 14 2000
end
classcanvas 128261 class_ref 145541 // Timeline
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 84 95 2000
xyz 43 87 2000
end
classcanvas 129029 class_ref 152197 // Sequence
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 161 252 2000
xyz 124 194 2000
end
classcanvas 129157 class_ref 152325 // Binding
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 124 175 2000
xyz 124 87 2000
end
classcanvas 129285 class_ref 128389 // Track
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 247 194 3005
end
classcanvas 130437 class_ref 128005 // SessionImpl
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 34 15 3005
end
classcanvas 130821 class_ref 167429 // BusMO
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 229 88 2000
end
classcanvas 131077 class_ref 138117 // Pipe
draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default member_max_width 0 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 show_stereotype_properties default
xyz 318 88 3005
end
textcanvas 131845 "»global pipes«"
xyzwh 245 73 2005 69 13
relationcanvas 129797 relation_ref 193413 // <unidirectional association>
decenter_end 409
from ref 129157 z 1999 to ref 129029
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 130181 relation_ref 193541 // <dependency>
from ref 128261 z 1999 to ref 129157
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 130309 relation_ref 193669 // <dependency>
from ref 129029 z 1999 to ref 129285
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 130565 relation_ref 184709 // <directional composition>
from ref 130437 z 1999 to ref 128261
role_a_pos 80 69 3000 no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 130693 relation_ref 193797 // <unidirectional association>
from ref 130437 z 1999 to ref 128005
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 130949 relation_ref 193925 // <directional aggregation>
from ref 129157 z 1999 to ref 130821
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
relationcanvas 131717 relation_ref 194053 // <unidirectional association>
from ref 130821 z 1999 to ref 131077
no_role_a no_role_b
no_multiplicity_a no_multiplicity_b
end
end

View file

@ -25,10 +25,10 @@ classinstancecanvas 128901 classinstance_ref 139269 //
xyz 96 211 2000
end
classinstancecanvas 130693 classinstance_ref 139397 //
xyz 319 251 2000
xyz 319 191 2000
end
classinstancecanvas 130949 classinstance_ref 139525 //
xyz 313 211 2000
xyz 313 157 2000
end
classinstancecanvas 131333 classinstance_ref 139653 //
xyz 319 308 2000
@ -52,7 +52,7 @@ classinstancecanvas 133637 classinstance_ref 140421 //
xyz 503 308 2000
end
classinstancecanvas 133893 classinstance_ref 140677 //
xyz 492 211 2000
xyz 492 252 2000
end
classinstancecanvas 134021 classinstance_ref 140805 //
xyz 562 129 2000
@ -84,12 +84,15 @@ packagecanvas 137477
end
packagecanvas 137605
package_ref 132229 // Session
name_in_tab yes xyzwh 15 25 1994 456 408
name_in_tab yes xyzwh 15 25 1984 456 408
end
note 137733 "top-level Timeline"
xyzwh 91 263 2000 64 45
note 137861 "virtual clip"
xyzwh 379 233 2010 69 35
xyzwh 393 235 2010 69 35
classinstancecanvas 138117 classinstance_ref 139653 //
xyz 319 252 2015
end
objectlinkcanvas 129029 norel
from ref 128773 z 1999 to ref 128901
no_role_a no_role_b
@ -117,9 +120,6 @@ objectlinkcanvas 129797 norel
from ref 128261 z 1999 to point 223 315
line 130437 z 1999 to ref 128645
no_role_a no_role_b
objectlinkcanvas 130821 norel
from ref 128389 z 1999 to ref 130693
no_role_a no_role_b
objectlinkcanvas 131077 norel
from ref 130693 z 1999 to ref 130949
no_role_a no_role_b
@ -136,11 +136,6 @@ objectlinkcanvas 132229 norel
from ref 131333 z 1999 to point 342 351
line 132357 z 1999 to ref 131589
no_role_a no_role_b
objectlinkcanvas 132485 norel
geometry VH
from ref 130693 z 1999 to point 342 282
line 132613 z 1999 to ref 131717
no_role_a no_role_b
objectlinkcanvas 133253 norel
geometry VH
from ref 128133 z 1999 to point 223 137
@ -156,6 +151,19 @@ objectlinkcanvas 134917 norel
from ref 133125 z 1999 to point 259 61
line 135045 z 1999 to ref 134789
no_role_a no_role_b
objectlinkcanvas 138245 norel
from ref 128389 z 1999 to ref 138117
no_role_a no_role_b
objectlinkcanvas 138373 norel
geometry VH
from ref 138117 z 2004 to point 342 282
line 138629 z 2004 to ref 131717
no_role_a no_role_b
objectlinkcanvas 138885 norel
decenter_begin 205
from ref 133893 z 1999 to point 411 198
line 139013 z 1999 to ref 130693
no_role_a no_role_b
line 130565 -_-_
from ref 128901 z 1999 to ref 128261
line 131205 -_-_
@ -168,8 +176,6 @@ line 135685 -_-_
from ref 133125 z 1999 to ref 134021
line 135941 -_-_
from ref 131333 z 1999 to ref 133637
line 136069 -_-_
from ref 130949 z 1999 to ref 133893
line 136581 -_-_
from ref 131589 z 1999 to ref 136197
line 136965 -_-_ decenter_end 181
@ -178,5 +184,7 @@ line 137093 -_-_
from ref 131461 z 1999 to ref 136325
line 137349 -_-_
from ref 137221 z 1999 to ref 128773
line 138757 -_-_
from ref 138117 z 1999 to ref 133893
preferred_whz 730 488 1
end

View file

@ -60,16 +60,17 @@ objectlinkcanvas 131973 norel
from ref 128901 z 1999 to ref 128261
no_role_a no_role_b
line 130053 -_-_
from ref 128389 z 1999 to ref 128645
from ref 128389 z 1999 to point 29 139
line 132101 z 1999 to ref 128645
line 130181 -_-_
from ref 128645 z 1999 to ref 128261
line 130309 -_-_
from ref 128773 z 1999 to ref 128901
line 130437 -_-_ geometry HVr
from ref 128901 z 1999 to point 428 316
from ref 128901 z 1999 to point 413 316
line 130565 z 1999 to ref 129413
line 130693 -_-_ geometry VH
from ref 128261 z 1999 to point 191 316
from ref 128261 z 1999 to point 175 316
line 130949 z 1999 to ref 129797
preferred_whz 556 483 1
end

View file

@ -2,16 +2,10 @@ window_sizes 1324 1020 270 1044 872 71
diagrams
classdiagram_ref 136453 // Session backbone
631 352 100 4 0 0
objectdiagram_ref 138885 // ModelAssetRelations
active objectdiagram_ref 138885 // ModelAssetRelations
730 488 100 4 0 0
classdiagram_ref 139141 // Meta-Asset Relations
469 451 100 4 0 0
classdiagram_ref 140293 // TypedLookup
721 697 100 4 0 0
active classdiagram_ref 141445 // Advice entities
635 331 100 4 0 0
objectdiagram_ref 141573 // Advice solving
556 483 100 4 0 0
classdiagram_ref 128133 // Session structure
835 697 100 4 0 0
end
show_stereotypes
selected
@ -26,17 +20,20 @@ open
class_ref 162821 // TypedID::Link
classview_ref 128389 // Controller Workings
class_ref 139653 // Session
class_ref 145541 // Timeline
class_ref 128133 // Seq
class_ref 160517 // Root
class_ref 128389 // Track
class_ref 152325 // Binding
class_ref 129797 // ExplicitPlacement
class_ref 129029 // Effect
class_ref 139909 // LocatingPin
class_ref 152453 // PlacementRef
classrelation_ref 178437 // <realization>
class_ref 153733 // QueryFocusStack
classview_ref 128261 // Builder Workings
usecaseview_ref 128261 // config examples
class_ref 133253 // Frame
classview_ref 128133 // Engine Workings
class_ref 164485 // Request
class_ref 164613 // Provision
class_ref 166021 // ActiveProvision

View file

@ -1,6 +1,6 @@
format 58
"lumiera"
revision 63
revision 64
modified_by 5 "hiv"
cpp_root_dir "../../src/"

View file

@ -1000,49 +1000,41 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
}
//}}}</pre>
</div>
<div title="BindingMO" modifier="Ichthyostega" modified="201007110149" created="200905210144" tags="def design discuss SessionLogic" changecount="17">
<pre>Sometimes, two entities within the [[Session]] are deliberately associated, and this association has to carry some specific mappings between properties or facilities within the entities to be linked together. When this connection isn't just the [[Placement]] of an object, and isn't just a logical or structural relationship either &amp;mdash; then we create an explicit Binding object to be stored into the session.
* When connecting a [[Sequence]] to a certain [[Timeline]], we also establish a mapping between the possible media stream channels produced by the sequence and the real output slots found within the timeline.
* similarly, using a sequence within a [[meta-clip|VirtualClip]] requires to remember such a mapping.
* another example is the root [[scope|PlacementScope]], which (conceptually) is a link between the definition part of the Session and the graph of MObjects, which are the session's contents.
<div title="BindingMO" modifier="Ichthyostega" modified="201011252205" created="200905210144" tags="def design discuss Model SessionLogic" changecount="33">
<pre>Binding-~MObjects are used to associate two entities within the high-level model.
More specifically, such a binding serves
* to outfit any top-level [[Timeline]] with real content, which is contained within a [[Sequence]]
* to build a VirtualClip, that is to link a complete sequence into another sequence, where it appears like a new virtual media or clip.
!Properties of a Binding
Binding is a relation entity, maintaining a link between parts of the session. This 1:1 relation may be part of a n:1 (or maybe even n:m?) relation. In addition to representing this link, a binding allows to maintain a set of ''mappings'' attached to this link.
This creates a typing related problem: In order to maintain the link and the mappings, in each case we need a common denominator to subsume the elements to be maintained.
* in the case of the basic link, this common denominator is given by the basic structure of the HighLevelModel: ~MObjects attached by Placements. Consequently, the link maintained through a binding is limited to linking together first-class entities within the model, and the implementation is tied into the existing mechanisms for associating Placements (&amp;rarr; PlacementScope and PlacementIndex)
* in the case of the attached mappings it seems we're best off limiting ourselves to symbolic mappings (ID mappings). Because, going beyond that would either create sub-groupings (based on varying target types to be mapped), or push the »everything is an object« approach beyond the beneficial level.
!Critique {{red{WIP 12/09}}}
Now I'm in doubt if there is any point in treating the &quot;binding&quot; in a abstract fashion. Is there any common denominator? It seems there is just a common conceptional pattern, but mapping this pattern onto distinct types (classes) seems unnecessary. Rather, we have three very similar kinds of ~MObjects:
* ModelRootMO
* BindingMO
* [[Track]]
While each of these actually represents a high-level concept (the session, the timeline(s) the sequence(s)) and moreover links to other parts and provides mappings, it seems there is no re-usable similarity at the code level.
//According to this reasoning, I should proceed rather with these three distinct entities and postpone any search for similarities to a later refactoring round.//
Binding is a relation entity, maintaining a link between parts of the session. Actually this link is achieved somewhat indirect: The binding itself is an MObject, but it points to a [[sequence asset|Sequence]]. Moreover, in case of the (top-level) timelines, there is a timeline asset acting as a frontend for the ~BindingMO.
* the binding exposes special functions needed to implement the timeline {{red{planned as of 11/10}}}
* similarly, the binding exposes functions allowing to wrap up the bound sequence as VirtualMedia (when acting as VirtualClip).
* the Binding holds an OutputMapping -- allowing to specify, resolve and remember [[output designations|OutputDesignation]]
Note: there are other binding-like entities within the model, which are deliberately not subsumed below this specification, but rather implemented stand alone.
&amp;rarr; see also SessionInterface
!Problems and Questions {{red{WIP 3/10}}}
Meanwhile I've settled down on implementing the [[top-level entities|Timeline]] as façade assets, backed by a {{{Placement&lt;Binding&gt;}}}. But the addressing and mapping of media channels still remains unsettled. Moreover, what happens when binding the sequence into a VirtualClip?
* because a Binding was assumed to link two entities, I concluded that the binding is dependent on those entities
* but then the two cases don't match:
** Timeline is an asset, not an MObject. Having a Timeline MObject would clearly be redundant. But then, consequently, //binding has to provide the global pipes,// because we need the possibility to attach effects to them (by placing the effects into the binding's scope)
** to the contrary, a VirtualClip requires somehow a ClipMO, which then in turn would need a channel configuration
*** so either, we could rework the clip asset into such a channel configuration (it looks pretty much redundant otherwise)
*** or the binding could take on the role of the channel configuration (which would be more in-line with the first case)
** unfortunately, both solutions bring the binding rather on the level of an asset (a media or channel configuration).
* //multiplicity// is yet another open question:
** can multiple placements refer to the same binding?
** what would be the semantics or such an arrangement?
** if we decide against it, what happens if we nevertheless encounter this situation?
&amp;harr; related to the handling of MultichannelMedia, which likewhise needs to be re-adjusted meanwhile!
&amp;rArr; {{red{rework of the model 6/10}}} taking these problems into account. Mostly cleanup and straightening. See AssetModelConnection
!Implementation
On the implementation side, we use a special kind of MObject, acting as an anchor and providing an unique identity. Like any ~MObject, actually a placement establishes the connection and the scope, and typically constitutes a nested scope (e.g. the scope of all objects //within// the sequence to be bound into a timeline)
Binding can be considered an implementation object, rarely to be created directly. Yet it is part of the high-level model
{{red{WIP 11/10}}}: it is likely that -- in case of creating a VirtualClip -- BindingMO will be hooked up behind another façade asset, acting as ''virtual media''
!!!channel / output mapping {{red{WIP 11/10}}}
The Binding-~MObject stores an OutputMapping. Basically this, together with OutputDesignation, implements the mapping behaviour
* during the build process, output designation(s) will be retrieved for each pipe.
* indirect and relative designations are to resolved; the relative ones are forwarded to the next enclosing binding
* in any case, the result is an direct WiringPlug, which can then be matched up and wired
* but in case of implementing a virtual clip, in addition to the direct wiring...
** a relative output designation (the N^^th^^ channel of this kind) is carried over to the target scope to be re-resolved there.
** any output designation specification yields a summation pipe at the binding, i.e. a position corresponding to the global pipes when using the same sequence as timeline.
** The output of these summation pipes is treated like a media channels
** but for each of those channels, an OutputDesignation is //carried over//&amp;nbsp; into the target (virtual clip)
*** now, if a distinct output designation can be determined at this placement of the virtual clip, it will be used for the further routing
*** otherwise, we try to re-evaluate the original output designation carried over. &lt;br/&gt;Thus, routing will be done as if the original output designation was given at this placement of the virtual clip.
</pre>
</div>
<div title="BindingScopeProblem" modifier="Ichthyostega" modified="201010021417" created="200910181435" tags="SessionLogic spec" changecount="20">
@ -1259,6 +1251,14 @@ at the lowest level within the builder there is the step of building a //connect
&amp;rarr;see also: BuilderPrimitives for the elementary working situations corresponding to each of these [[builder moulds|BuilderMould]]
</pre>
</div>
<div title="BusMO" modifier="Ichthyostega" modified="201011210111" created="201011210045" tags="def Model" changecount="7">
<pre>''Bus-~MObjects'' create a scope and act as attachment point for building up [[global pipes|GlobalPipe]] within each timeline. While [[Sequence]] is a frontend -- actually implemented by attaching a root-[[Track]] object -- for //each global pipe// a BusMO is attached as child scope of the [[binding object|BindingMO]], which in turn actualy implements either a timeline or a [[meta-clip|VirtualClip]].
* each global pipe corresponds to a bus object, which thus refers to the respective ~Pipe-ID
* bus objects may be nested, forming a //subgroup//
* the placement of a bus holds a WiringClaim, denoting that this bus //claims to be the corresponding pipe.//
* by default, a timeline is outfitted with one video and one sound master bus
</pre>
</div>
<div title="ColorPalette" modifier="Ichthyostega" modified="200807131329" created="200706190033" tags="excludeMissing" changecount="14">
<pre>Background: #fefefd
Foreground: #000
@ -1563,15 +1563,16 @@ As we don't have a Prolog interpreter on board yet, we utilize a mock store with
{{{default(Obj)}}} is a predicate expressing that the object {{{Obj}}} can be considered the default setup under the given conditions. Using the //default// can be considered as a shortcut for actually finding a exact and unique solution. The latter would require to specify all sorts of detailed properties up to the point where only one single object can satisfy all conditions. On the other hand, leaving some properties unspecified would yield a set of solutions (and the user code issuing the query had to provide means for selecting one soltution from this set). Just falling back on the //default// means that the user code actually doesn't care for any additional properties (as long as the properties he //does// care for are satisfied). Nothing is said specifically on //how//&amp;nbsp; this default gets configured; actually there can be rules //somewhere,// and, additionally, anything encountered once while asking for a default can be re-used as default under similar circumstances.
&amp;rarr; [[implementing defaults|DefaultsImplementation]]</pre>
</div>
<div title="DesignDecisions" modifier="Ichthyostega" modified="201009240010" created="200801062209" tags="decision design discuss Concepts" changecount="28">
<div title="DesignDecisions" modifier="Ichthyostega" modified="201011210034" created="200801062209" tags="decision design discuss Concepts" changecount="33">
<pre>Along the way of working out various [[implementation details|ImplementationDetails]], decisions need to be made on how to understand the different facilities and entities and how to tackle some of the problems. This page is mainly a collection of keywords, summaries and links to further the discussion. And the various decisions should allways be read as proposals to solve some problem at hand...
''Everything is an object'' &amp;mdash; yes of course, that's a //no-brainer,// todays. Rather, important is to note what is not &quot;an object&quot;, meaning it can't be arranged arbitrarily
* we have one and only one global [[Session]] which directly contains a collection of multiple [[Sequences|Sequence]] and is associated with a globally managed collection of [[assets|Asset]]. We don't utilise scoped variables here (no &quot;mandantisation&quot;); if e.g. a media has been //opened,// it is just plain //globally known//&amp;nbsp; as asset.
* we have one and only one global [[Session]] which directly contains a collection of multiple [[Timelines|Timeline]] and is associated with a globally managed collection of [[assets|Asset]]. We don't utilise scoped variables here (no &quot;mandantisation&quot;); if a media has been //opened,// it is just plain //globally known//&amp;nbsp; as asset.
* the [[knowledge base|ConfigRules]] is just available globally. Obviously, the session gets a chance to install rules into this knowledge base, but we don't stress ownership here.
* we have a [[Fixture]] which acts as isolation layer towards the render engine and is (re)built automatically.
The high-level view of the tangible entities within the session is unified into a ''single tree'' -- with the notable exception of [[external outputs|OutputManagement]] and the [[assets|Asset]], which are understood as representing a //bookkeeping view// and kept separate from the //things to be manipulated// (MObjects).
We ''separate'' processing (rendering) and configuration (building). We have a [[Builder]] which creates a network of [[render nodes|ProcNode]], to be processed by //pulling data // from some [[Pipe]]
We ''separate'' processing (rendering) and configuration (building). The [[Builder]] creates a network of [[render nodes|ProcNode]], to be processed by //pulling data // from some [[Pipe]]
''Objects are [[placed|Placement]] rather'' than assembled, connected, wired, attached. This is more of a rule-based approach and gives us one central metaphor and abstraction, allowing us to treat everything in an uniform manner. You can place it as you like, and the builder tries to make sense out of it, silently disabling what doesn't make sense.
An [[Sequence]] is just a collection of configured and placed objects (and has no additional, fixed structure). [[Tracks|Track]] form a mere organisational grid, they are grouping devices not first-class entities (a track doesn't &quot;have&quot; a pipe or &quot;is&quot; a video track and the like; it can be configured to behave in such manner by using placements though). [[Pipes|Pipe]] are hooks for making connections and are the only facility to build processing chains. We have global pipes, and each clip is built around a lokal [[source port|ClipSourcePort]] &amp;mdash; and that's all. No special &quot;media viewer&quot; and &quot;arranger&quot;, no special role for media sources, no commitment to some fixed media stream types (video and audio). All of this is sort of pushed down to be configuration, represented as asset of some kind. For example, we have [[processing pattern|ProcPatt]] assets to represent the way of building the source network for reading from some media file (including codecs treated like effect plugin nodes)
@ -1902,11 +1903,25 @@ For this Lumiera design, we could consider making GOP just another raw media dat
&amp;rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
</pre>
</div>
<div title="GlobalPipe" modifier="Ichthyostega" modified="201007190107" created="201007110200" tags="Model design spec draft" changecount="22">
<div title="GlobalPipe" modifier="Ichthyostega" modified="201011202343" created="201007110200" tags="Model spec draft" changecount="29">
<pre>Each [[Timeline]] has an associated set of global [[pipes|Pipe]] (global busses), similar to the subgroups of a sound mixing desk.
In the typical standard configuration, there is (at least) a video master and a sound master pipe. Like any pipe, ingoing connections attach to the input side, attached effects form a chain, where the last node acts as exit node. The ~Pipe-ID of such a global bus can be used to route media streams, allowing the global pipe to act as a summation bus bar.
&amp;rarr; discussion and design rationale of [[global pipes|GlobalPipeDesign]]
!{{red{WIP}}} Design problem with global Pipes
!Properties and decisions
* each timeline carries its own set of global pipes, as each timeline is an top-level element on its own
* like all [[pipes|Pipe]] the global ones are kept separated per stream (proto)type
* any global pipe //not// connected to another OutputDesignation automatically creates a ModelPort
* global pipes //do not appear automagically just by sending output to them// -- they need to be set up explicitly
* the top-level (BusMO) of the global pipes isn't itself a pipe. Thus the top-level of the pipes forms a list (typically a video and sound master)
* below, a tree-like structure //may// be created, building upon the same scope based routing technique as used for the tracks
</pre>
</div>
<div title="GlobalPipeDesign" modifier="Ichthyostega" modified="201011210016" created="201011202308" tags="design decision discuss" changecount="6">
<pre>//This page serves to shape and document the design of the global pipes//
Many aspects regarding the global pipes turned out while clarifying other parts of ~Proc-Layer's design. For some time it wasn't even clear if we'd need global pipes -- common video editing applications get on without. Mostly it was due to the usefulness of the layout found on sound mixing desks, and a vague notion to separate time-dependant from global parts, which finally led me to favouring such a global facility. This decision then helped in separating the concerns of timeline and sequence, making the //former// a collection of non-temporal entities, while the latter concentrates on time varying aspects.
!Design problem with global Pipes
actually building up the implementation of global pipes seems to pose a rather subtle design problem: it is difficult to determine how to do it //right.//
To start with, we need the ability to attach effects to global pipes. There is already an obvious way how to attach effects to clips (=local pipes), and thus it's desirable to handle it the same way for global pipes. At least there should be a really good reason //not//&amp;nbsp; to do it the same way. Thus, we're going to attach these effects by placement into the scope of another placed MObject. And, moreover, this other object should be part of the HighLevelModel's tree, to allow using the PlacementIndex as implementation. So this reasoning brings us to re-using or postulating some kind of object, while lacking a point or reference //outside this design considerations//&amp;nbsp; to justify the existence of the corresponding class or shaping its properties on itself. Which means &amp;mdash; from a design view angle &amp;mdash; we're entering slippery ground.
!!!~Model-A: dedicated object per pipe
@ -1914,7 +1929,7 @@ Just for the sake of symmetry, for each global pipe we'd attach some suitable ~M
!!!~Model-B: attaching to the container
Acknowledging the missing justification, we could instead use //just something to attach// &amp;mdash; and actually handle the real association elsewhere. The obvious &quot;something&quot; in this case would be the BindingMO, which already acts as implementation of the timeline (which is a façade asset). Thus, for this approach, the bus-level effects would be attached as direct children of the {{{Placement&lt;BindingMO&gt;}}}, just for the sake of beeing attached and stored within the session, with an additional convention for the actual ordering and association to a specific pipe. The Builder then would rather query the ~BindingMO to discover and build up the implementation of the global pipes in terms of the render nodes.
!!!Comparision
!!!Comparison
While there might still be some compromises or combined solutions &amp;mdash; to support the decision, the following table detailes the handling in each case
|&gt;| !~Model-B|!~Model-A |
|Association: | by plug in placement|by scope |
@ -1924,7 +1939,20 @@ While there might still be some compromises or combined solutions &amp;mdash; to
|Extras: | ? |tree-like bus arrangement,&lt;br/&gt; multi-stream bus |
So through this detailed comparison ''~Model-A looks favourable'': while the other model requires us to invent a good deal of the handling specifically for the global pipes, the former can be combined from patterns and solutions already used in other parts of the model, plus it allows some interesting extensions.
On a second thought, the fact that the Bus-~MObject is rather void of any specific meaning doesn't weight so much: As the Builder is based on the visitor pattern, the individual objects can be seen as //algebraic data types.// Besides, there is at least one little bit of specific functionality: a Bus object actually needs to //claim//&amp;nbsp; to be the OutputDesignation, by referring to the same ~Pipe-ID used in other parts of the model to request output routing to this Bus. Without this match on both ends, an ~OutputDesignation may be mentioned at will, but no connection whatsoever will happen.
On a second thought, the fact that the [[Bus-MObject|BusMO]] is rather void of any specific meaning doesn't weight so much: As the Builder is based on the visitor pattern, the individual objects can be seen as //algebraic data types.// Besides, there is at least one little bit of specific functionality: a Bus object actually needs to //claim//&amp;nbsp; to be the OutputDesignation, by referring to the same ~Pipe-ID used in other parts of the model to request output routing to this Bus. Without this match on both ends, an ~OutputDesignation may be mentioned at will, but no connection whatsoever will happen.
!{{red{WIP}}} Structure of the global pipes
;creating global pipes automatically?
:defining the global bus configuration is considered a crucial part of each project setup. Lumiera isn't meant to support fiddling around thoughtlessly. The user should be able to rely on crucial aspects of the global setup never being changed without notice.
;isn't wiring and routing going to be painful then?
:routing is scope based and we employ a hierarchical structure, so subgroups are routed automatically. Moreover, wiring is done based on best match regarding the stream type. We might consider feeding all non-connected output designations to the GUI after the build process, to allow short-cuts for creating further buses.
;why not making buses just part of the track tree?
:anything on a track has a temporal extension and may vary -- while it's the very nature of the global pipes to be static anchor points.
;why not having one grand unified root, including the outputs?
:you might consider that a matter of taste (or better common-sense). Things different in nature should not be forced into uniformity
;should global pipes be arranged as list or tree?
:sound mixing desks use list style arrangement, and this has proven to be quite viable, when combined with the ability to //send over// output from one mixer stripe to the input of another, allowing to build arbitrary complex filter matrices. On the other hand, organising a mix in //subgroups// can be considered best practice. This leads to arranging the pipes //as wood:// by default and on top level as list, optionally expanding into a subtree with automatic rooting, augmented by the ability to route any output to any input (cycles being detected and flagged as error).
</pre>
</div>
<div title="GuiCommunication" modifier="Ichthyostega" modified="200812050555" created="200812050543" tags="GuiIntegration draft" changecount="2">
@ -2014,7 +2042,7 @@ Besides routing to a global pipe, wiring plugs can also connect to the source po
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.
</pre>
</div>
<div title="ImplementationDetails" modifier="Ichthyostega" modified="201001070900" created="200708080322" tags="overview" changecount="38">
<div title="ImplementationDetails" modifier="Ichthyostega" modified="201011190301" created="200708080322" tags="overview" changecount="39">
<pre>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]]
@ -2041,19 +2069,21 @@ Finally, this example shows an ''automation'' data set controlling some paramete
* create an uniform pattern for [[passing and accessing object collections|ForwardIterator]]
* decide on SessionInterface and create [[Session datastructure layout|SessionDataMem]]
* shaping the GUI/~Proc-Interface, based on MObjectRef and the [[Command frontend|CommandHandling]]
* defining PlacementScope in order to allow for [[discovering session contents|Query]]</pre>
* defining PlacementScope in order to allow for [[discovering session contents|Query]]
* working out a [[Wiring concept|Wiring]] and the foundations of OutputManagement
</pre>
</div>
<div title="ImplementationGuidelines" modifier="Ichthyostega" modified="200910311727" created="200711210531" tags="Concepts design discuss" changecount="16">
<div title="ImplementationGuidelines" modifier="Ichthyostega" modified="201011190306" created="200711210531" tags="Concepts design discuss" changecount="17">
<pre>!Observations, Ideas, Proposals
''this page is a scrapbook for collecting ideas'' &amp;mdash; please don't take anything noted here too literal. While writing code, I observe that I (ichthyo) follow certain informal guidelines, some of which I'd like to note down because they could evolve into general style guidelines for the Proc-Layer code.
* ''Inversion of Control'' is the leading design principle.
* but deliberately we stay just below the level of using Dependency Injection. Singletons and call-by-name are good enough. We're going to build //one// application, not any conceivable application.
* avoid doing anything non-local during the startup phase or shutdown phase of the application. consequently, always prefer using an explicit lumiera::Singleton&lt;T&gt; over using an static instance directly, thus yielding better control when the ctor and dtor will be invoked.
* write error handling code only if the error situation can be actually //handled// at this place. Otherwise, be prepared for exceptions just passing by and thus handle any resources by &quot;resource acquisition is initialisation&quot; (RAII). Remember: error handling defeats decoupling and encapsulation
* (almost) never {{{delete}}} an object directly, use {{{new}}} only when some smart pointer is at hand.
* when user/client code is intended to create objects, make the ctor protected and provide a factory member called {{{create}}} instead, returning a smart pointer
* similarly, when we need just one instance of a given service, make the ctor protected and provide a factory member called {{{instance}}}, to be implemented by the lumiera::[[Singleton]] factory.
* whenever possible, prefer this (lazy initialised [[Singleton]]) approach and avoid static initialisation magic
* avoid doing anything non-local during the startup phase or shutdown phase of the application, especially avoid doing substantial work in any dtor.
* avoid asuming anything that can't be enforced by types, interfaces or signatures; this means: be prepared for open possibilities
* prefer {{{const}}} and initialisation code over assignment and active changes (inspired by functional programming)
</pre>
@ -2663,10 +2693,11 @@ And, last but not least, doing large scale allocations is the job of the backend
<div title="Model" modifier="Ichthyostega" modified="201003210021" created="201003210020" tags="overview" changecount="2">
<pre>Lumiera's Proc-Layer is built around //two interconnected models,// mediated by the [[Builder]]. Basically, the &amp;rarr;[[Session]] is an external interface to the HighLevelModel, while the &amp;rarr;RenderEngine operates the structures of the LowLevelModel.</pre>
</div>
<div title="ModelDependencies" modifier="Ichthyostega" modified="201006140007" created="201003020150" tags="SessionLogic Model operational spec draft img" changecount="35">
<div title="ModelDependencies" modifier="Ichthyostega" modified="201011220126" created="201003020150" tags="SessionLogic Model operational spec draft img" changecount="37">
<pre>Our design of the models (both [[high-level|HighLevelModel]] and [[low-level|LowLevelModel]]) relies partially on dependent objects being kept consitently in sync. Currently (2/2010), __ichthyo__'s assessment is to consider this topic not important and pervasive enough to justify building a dedicated solution, like e.g. a central tracking and registration service. An important point to consider with this assesment is the fact that the session implementation is beeing kept mostly single-threaded. Thus, lacking one central place to handle this issue, care has to be taken to capture and treat all the relevant individual dependencies properly at the implementation level.
!known interdependencies
[&gt;img[Fundamental object relations used in the session|uml/fig136453.png]]
* the session API relies on two kinds of facade like assets: [[Timeline]] and [[Sequence]], linked to the BindingMO and Track objects within the model respectively.
* conceptually, the DefaultsManagement and the AssetManager count as being part of the [[global model scope|ModelRootMO]], but, due to their importance, these facilities are accessible through an singleton interface.
* currently as of 2/2010 the exact dependency of the automation calculation during the render process onto the automation definitions within the HighLevelModel remains to be specified.
@ -2751,6 +2782,14 @@ These are used as token for dealing with other objects and have no identity of t
* these reference handles simply reflect the equality relation on placements, by virtue of comparing the hash-ID.
* besides, we could build upon the placement locating chain equivalence relations to define a semantic equivalence on ~MObjectRefs
</pre>
</div>
<div title="ModelPort" modifier="Ichthyostega" created="201011100234" tags="def" changecount="1">
<pre>Any point where output possibly might be produced. Model port entities are located within the [[Fixture]] &amp;mdash; model port as a concept spans the high-level and low-level view. A model port can be associated both to a pipe in the HighLevelModel and denote a specific ExitNode in the render nodes network.
A model port is rather derived than configured; it emerges when a pipe [[claims|WiringClaim]] an output desitnation and some other entity actually uses this designation as a target, either directly or indirecly. This match of provision and usage is detected during the build process and produces an entry in the fixture's model port table. These model ports in the fixture are keyed by ~Pipe-ID, thus each model port has an associated StreamType.
Model ports are the effective, resulting ouputs of each timeline; additional ports result from [[connecting a viewer|ViewerPlayConnection]]. Any render or display process happens at a model port.
</pre>
</div>
<div title="ModelRootMO" modifier="Ichthyostega" modified="200912110245" created="200912080307" tags="def" changecount="5">
@ -2878,17 +2917,17 @@ But because I know the opinions on this topc are varying (users tend to be delig
My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the render path in whole or partially or maybe even just for preview.
</pre>
</div>
<div title="OperationPoint" modifier="Ichthyostega" modified="200909041742" created="200805270334" tags="def impl Builder" changecount="8">
<div title="OperationPoint" modifier="Ichthyostega" modified="201011071905" created="200805270334" tags="def impl Builder" changecount="9">
<pre>A low-level abstraction within the [[Builder]] &amp;mdash; it serves to encapsulate the details of making multi-channel connections between the render nodes: In some cases, a node can handle N channels internally, while in other cases we need to replicate the node N times and wire each channel individually. As it stands, the OperationPoint marks the ''borderline between high-level and low-level model'': it is invoked in terms of ~MObjects and other entities of the high-level view, but internally it manages to create ProcNode and similar entities of the low-level model.
The operation point is provided by the current BuilderMould and used by the [[processing pattern|ProcPatt]] executing within this mould and conducting the current build step. The operation point's interface allows //to abstract//&amp;nbsp; these details, as well as to //gain additional control//&amp;nbsp; if necessary (e.g. addressing only one of the channels). The most prominent build instruction used within the processing patterns (which is the instruction {{{&quot;attach&quot;}}}) relies on the aforementioned //approach of abstracted handling,// letting the operation point determine automatically how to make the connection.
This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, which, together with information accessible at the the [[render node interface|ProcNode]] and from the [[referred processing assets|ProcAsset]], with the help of the [[connection manager|ConManager]] allows to figure out what's possible and how to do the desired connections. Additionally, in the course of deciding about possible connections, the PathManager is consulted to guide strategic decisions regarding the [[render node configuration|NodeConfiguration]], possible type conversions and the rendering technology to employ.
This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, which, together with information accessible at the [[render node interface|ProcNode]] and from the [[referred processing assets|ProcAsset]], with the help of the [[connection manager|ConManager]] allows to figure out what's possible and how to do the desired connections. Additionally, in the course of deciding about possible connections, the PathManager is consulted to guide strategic decisions regarding the [[render node configuration|NodeConfiguration]], possible type conversions and the rendering technology to employ.
</pre>
</div>
<div title="OutputDesignation" modifier="Ichthyostega" modified="201009242320" created="201006220126" tags="Model draft design discuss" changecount="42">
<pre>__6/2010__: an ever recurring (and yet unsolved) problem in the design of Luimiera's ~Proc-Layer is how to refer to output destinations, and how to organise them.
To get ahead with this problem, I'll start collecting observations, relations and drafts on this tiddler.
<div title="OutputDesignation" modifier="Ichthyostega" modified="201011190258" created="201006220126" tags="Model draft design discuss" changecount="50">
<pre>An ever recurring problem in the design of Luimiera's ~Proc-Layer is how to refer to output destinations, and how to organise them.
Wiring the flexible interconnections between the [[pipes|Pipe]] should take into account both the StreamType and the specific usage context ([[scope|PlacementScope]]) -- and the challenge is to avoid hard-linking of connections and tangling with the specifics of the target to be addressed and connected. This page, started __6/2010__ by collecting observations to work out the relations, arrives at defining a //key abstraction// of output management.
!Observations
* effectively each [[Timeline]] is known to expose a set of global Pipes
@ -2923,21 +2962,30 @@ System level output connections seem to be an exception to the above rule. There
The immediate consequence is that a [[Pipe]] with the given ID exists as an accountable entity. Only if &amp;mdash; additionally &amp;mdash; a suitable object within the model //claims to root this pipe,// a connection to this designation is wired, using an appropriate [[processing pattern|ProcPatt]]. A further consequence then is for the mentioned output designation to become a possible candidate for a ModelPort, an exit node of the built render nodes network. By default, only those designations without further outgoing connections actually become active model ports (but an existing and wired pipe exit node can be promoted to a model port explicitly).
&amp;rarr; OutputManagement
!Mapping of output designations
An entire sequence can be embedded within another sequence as a VirtualClip. While for a simple clip there is a Clip-~MObject placed into the model, holding an reference to a media asset, in case of a virtual clip an BindingMO takes on the role of the clip object. Note that BindingMO also acts as [[Timeline]] implementation &amp;mdash; indeed the same sequence might be bound simultaneously as a timeline and into a virtual clip. This flexibility creates a special twist, as the contents of this sequence have no way of finding out if they're used as timeline or embedded virtual clip. So parts of this sequence might mention a OutputDesignation which, when using the sequence as virtual clip, needs to be translated into a virtual media channel, which can be treated in the same fashion as any channel (video, audio,...) found within real media. Especially, a new output designation has to be derived in a sensible way, which largely depends on how the original output designation has been specified
* a direct output designation specicfiation from within the sequence is captured and translated into a summation pipe at a position corresponding to the global pipes when using the same sequence as timeline. The output of this summation pipe is treated like a media channel
** now, if a distinct output designation can be determined at this placement of the virtual clip, it will be used for the further routing
** otherwise, the routing will be done as if the original output designation was given at this placement of the virtual clip.
* a relative output designation (the N^^th^^ channel of this kind) is just carried over to the enclosing scope.
!!Challenge: mapping of output designations
An entire sequence can be embedded within another sequence as a VirtualClip. While for a simple clip there is a Clip-~MObject placed into the model, holding an reference to a media asset, in case of a virtual clip an BindingMO takes on the role of the clip object. Note that BindingMO also acts as [[Timeline]] implementation &amp;mdash; indeed the same sequence might be bound simultaneously as a timeline and into a virtual clip. This flexibility creates a special twist, as the contents of this sequence have no way of finding out if they're used as timeline or embedded virtual clip. So parts of this sequence might mention a OutputDesignation which, when using the sequence as virtual clip, needs to be translated into a virtual media channel, which can be treated in the same fashion as any channel (video, audio,...) found within real media. Especially, a new output designation has to be derived in a sensible way, which largely depends on how the original output designation has been specified.
&amp;rarr; see OutputMapping regarding details and implementation of this mapping mechanism
!Using output designations
!Output designation definition
OutputDesignation is a handle, denoting a target [[Pipe]] to connect.
It exposes a function to resolve to a Pipe, and to retrieve the StreamType of that resolved output. It can be ''defined'' either explicitly by ~Pipe-ID, or by an indirect or relative specification. The later cases are resolved on demand only (which may be later and might change the meaning depending on the context). It's done this way intentionally to gain flexibility and avoid hard wiring (=explicit ~Pipe-ID)
!!!Implementation notes
Thus the output designation needs to be a copyable value object, but opaque beyond that. Mandated by the various ways to specify an output designation, a hidden state arises regarding the partial resolution. The implementation solves that dilemma by relying on the [[State|http://en.wikipedia.org/wiki/State_pattern]] pattern in combination with an opaque in-place buffer.
!Use of output designations
While actually data frames are //pulled,// on a conceptual level data is assumed to &quot;flow&quot; through the pipes from source to output. This conceptual (&quot;high level&quot;) model of data flow is comprised of the pipes (which are rather rigid), and flexible interconnections. The purpose of an output designation is to specify where the data should go, especially through these flexible interconnections. Thus, when reaching the exit point of a pipe, an output designation will be //queried.// Finding a suitable output designation involves two parts:
* first of all, we need to know //what to route// &amp;mdash; kind of the traits of the data. This is given by the //current pipe.//
* first of all, we need to know //what to route// -- kind of the traits of the data. This is given by the //current pipe.//
* then we'll need to determine an output designation //suitable for this data.// This is given by a &quot;Plug&quot; (WiringRequest) in the placement, and may be derived.
* finally, this output designation will be //resolved// -- at least partially, resulting in a target pipe to be used for the wiring
As both of these specifications are given by [[Pipe]]-~IDs, the actual designation information may be reduced. Much can be infered from the circumstances, because any pipe includes a StreamType, and an output designation for an incompatible stream type (e.g. and audio output when the pipe currently in question deals with video) is irrelevant.
</pre>
</div>
<div title="OutputManagement" modifier="Ichthyostega" modified="201007190254" created="201007090155" tags="Model Rendering Player spec draft" changecount="17">
<div title="OutputManagement" modifier="Ichthyostega" modified="201011072240" created="201007090155" tags="Model Rendering Player spec draft" changecount="18">
<pre>//writing down some thoughts//
* ruled out the system outputs as OutputDesignation.
@ -2953,7 +3001,7 @@ From the implementation side, the only interesting exit nodes are the ones to be
* __playback__ always happens at a viewer element
!Attaching and mapping of exit nodes
[[Output designations|OutputDesignation]] are created by using a [[Pipe]]-ID and &amp;mdash; at the same time &amp;mdash; by some object //claiming to root this pipe.// The applicability of this pattern is figured out dynamically while building the render network, resulting in a collection of model ports as part of the current [[Fixture]]. A RenderProcess can be started to pull from these active exit points of a given timeline. Besides, when the timeline enclosing these model ports is [[connected to a viewer|ViewerPlayConnection]], an //output network is built,// to allow hooking exit points to the viewer component. Both cases encompass a mapping of exit nodes to actual output channels. Usually, this mapping relies on relative addressing of the output sinks, starting connections at the &quot;first of each kind&quot;.
[[Output designations|OutputDesignation]] are created by using a [[Pipe]]-ID and &amp;mdash; at the same time &amp;mdash; by some object //claiming to root this pipe.// The applicability of this pattern is figured out dynamically while building the render network, resulting in a collection of model ports as part of the current [[Fixture]]. A RenderProcess can be started to pull from these active exit points of a given timeline. Besides, when the timeline enclosing these model ports is [[connected to a viewer|ViewerPlayConnection]], an [[output network|OutputNetwork]] //is built to allow hooking exit points to the viewer component.// Both cases encompass a mapping of exit nodes to actual output channels. Usually, this mapping relies on relative addressing of the output sinks, starting connections at the &quot;first of each kind&quot;.
We should note that in both cases this mapping operation is controlled and driven by the output side of the connection: A viewer has fixed output capabilities, and rendering targets a specific container format, again with fixed and pre-settled channel configuration (when configurting a render process, it might be necessary to account for //possible kinds of output streams,// so to provide a sensible pre-selection of possible output container formats for the user to select from). Thus, as a starting point, we'll create a default configured mapping, assigning channels in order. This mapping then should be exposed to modification and tweaking by the user. For rendering, this is part of the render options dialog, while in case of a viwer connection, a switch board is created to allow modifying the default mapping.
@ -2964,6 +3012,38 @@ Any external output sink is managed as a [[slot|DisplayerSlot]] in the ~OutputMa
&amp;rarr; see also the PlayerDummy
</pre>
</div>
<div title="OutputMapping" modifier="Ichthyostega" modified="201011270311" created="201011080238" tags="Model spec draft" changecount="23">
<pre>An output mapping serves to //resolve//&amp;nbsp; [[output designations|OutputDesignation]].
!Mapping situations
;external outputs
:external outputs aren't addressed directly. Rather we set up a default (channel) mapping, which then can be overridden by local rules.
:Thus, in this case we query with an internal OutputDesignation as parameter and expect an OutputManager //slot//
;viewer connections
:any Timeline produces a number of [[model ports|ModelPort]]. On the other hand, any viewer exposes a small number of output designations, representing the image and sound output(s).
:Thus, in this case we resolve similar to a bus connection, possibly overridden by already pre-existing or predefined connections.
;switch board
:a viewer might receive multiple outputs and overlays, necessitating a user operated control to select what's actually to displayed
:Thus, in this case we need a backwards resolution at the lower end of the output network, to connect to the model port as defined by the switchboard
;global pipes or virtual media
:when binding a Sequence as Timeline or VirtualClip, a mapping from output designations used within the Sequence to virtual channels or global pipes is required
:Thus, in this case we need to associate output designations with ~Pipe-IDs encountered in the context according to some rules &amp;mdash; again maybe overridden by pre-existing connections
!Conclusions
All these mapping steps are listed here, because they exhibit a common pattern.
* the immediately triggering input key is a [[Pipe]]-ID (and thus provides a stream type); additional connection hints may be given.
* the mapped result draws from a limited selection of elements, which again can be keyed by ~Pipe-IDs
* the mapping is initialised based on default mapping rules acting as fallback
* the mapping may be extended by explicitly setting some associations
* the mapping itself is a stateful value object
* there is an //unconnected//&amp;nbsp; state.
!Implementation notes
Thus the mapping is a copyable value object, based on a associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places, where no distinct pipe-ID is explicitly specified. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to denote &quot;the second stream of this kind&quot;) to hint the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
First and foremost, mapping can be seen as a //functional abstraction.// As it's used at implementation level, encapsulation of detail types in't the primary concern, so it's a candidate for generic programming: For each of those use cases outlined above, a distinct mapping type is created by instantiating the {{{OutputMapping&lt;DEF&gt;}}} template with a specifically tailored definition context ({{{DEF}}}), which takes on the role of a strategy. Individual instances of this concrete mapping type may be default created and copied freely. This instantiation process includes picking up the concrete result type and building a functor object for resolving on the fly. Thus, in the way typical for generic programming, the more involved special details are moved out of sight, while being still in scope for the purpose of inlining. But there //is// a concern better to be encapsulated and concealed at the usage site, namely accessing the rules system. Thus mapping leads itself to the frequently used implementation pattern where there is a generic frontend as header, calling into opaque functions embedded within a separate compilation unit.
</pre>
</div>
<div title="Overview" modifier="Ichthyostega" modified="200906071810" created="200706190300" tags="overview img" changecount="13">
<pre>The Lumiera Processing Layer is comprised of various subsystems and can be separated into a low-level and a high-level part. At the low-level end is the [[Render Engine|OverviewRenderEngine]] which basically is a network of render nodes cooperating closely with the Backend Layer in order to carry out the actual playback and media transforming calculations. Whereas on the high-level side we find several different [[Media Objects|MObjects]] that can be placed into the session, edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the &quot;bookkeeping view&quot; of all the different &quot;things&quot; within each [[Session|SessionOverview]].
@ -3540,19 +3620,23 @@ DAMAGE.
<div title="PathManager" modifier="Ichthyostega" created="200909041748" tags="def Builder" changecount="1">
<pre>Facility guiding decisions regarding the strategy to employ for rendering or wiring up connections. The PathManager is querried through the OperationPoint, when executing the connection steps within the Build process.</pre>
</div>
<div title="Pipe" modifier="Ichthyostega" modified="200804110301" created="200801062110" tags="def decision" changecount="6">
<div title="Pipe" modifier="Ichthyostega" modified="201011220317" created="200801062110" tags="def decision" changecount="7">
<pre>Pipes play an central role within the Proc Layer, because for everything placed and handled within the session, the final goal is to get it transformed into data which can be retrieved at some pipe's exit port. Pipes are special facilities, rather like inventory, separate and not treated like all the other objects.
We don't distinguish between &quot;input&quot; and &quot;output&quot; ports &amp;mdash; rather, pipes are thought to be ''hooks for making connections to''. By following this line of thought, each pipe has an input side and an output side and is in itself something like a ''Bus'' or ''processing chain''. Other processing entities like effects and transitions can be placed (attached) at the pipe, resulting them to be appended to form this chain. Likewise, we can place [[wiring requests|WiringRequest]] to the pipe, meaning we want it connected so to send it's output to another destination pipe. The [[Builder]] may generate further wiring requests to fulfil the placement of other entities.
Thus //Pipes are the basic building blocks// of the whole render network. We distinguish ''global available'' Pipes, which are like the sum groups of a mixing console, and the ''lokal pipe'' or [[source ports|ClipSourcePort]] of the individual clips, which exist only within the duration of the corresponding clip. The design //limits the possible kinds of pipes // to these two types &amp;mdash; thus we can build local processing chains at clips and global processing chains at the global pipes of the session and that's all we can do. (because of the flexibility which comes with the concept of [[placements|Placement]], this is no real limitation)
The GUI can connect the viewer(s) to some pipe (and moreover can use [[probe points|ProbePoint]] placed like effects and connected to some pipe), and likewise, when starting a ''render'', we get the opportunity to specify the pipes to pull the data from. Pulling data from some pipe is the (only) way to activate the render nodes network reachable from this pipe.
Pipes are denoted and addressed by ~Pipe-IDs, implemented as ID of a pipe asset. Besides explicitly named pipes, there are some generic placeholder ~IDs for a standard configured pipe of a given type. This is done to avoid creating a separate ~Pipe-ID for each and every clip to build.
While pipes are rather rigid building blocks -- and especially are limited to a single StreamType without conversions, the interconnections or ''routing'' links to the contrary are more flexible. They are specified and controled through the use of an OutputDesignation, which, when fully resolved, should again yield a target ~Pipe-ID to connect. The mentioned resolution of an output designation typically involves an OutputMapping.
Similar structures and mechanisms are extended beyond the core model: The GUI can connect the viewer(s) to some pipe (and moreover can use [[probe points|ProbePoint]] placed like effects and connected to some pipe), and likewise, when starting a ''render'', we get the opportunity to specify the ModelPort (exit point of a GlobalPipe) to pull the data from. Pulling data from some pipe is the (only) way to activate the render nodes network reachable from this pipe.
&amp;rarr; [[Handling of Tracks|TrackHandling]]
&amp;rarr; [[Handling of Pipes|PipeHandling]]
</pre>
</div>
<div title="PipeHandling" modifier="Ichthyostega" modified="201007210309" created="200801101352" tags="spec" changecount="16">
<div title="PipeHandling" modifier="Ichthyostega" modified="201011220320" created="200801101352" tags="spec" changecount="19">
<pre>!Identification
Pipes are distinct objects and can be identified by their asset ~IDs. Besides, as for all [[structural assets|StructAsset]] there are extended query capabilities, including a symbolic pipe-id and a media (stream) type id. Any pipe can accept and deliver exactly one media stream kind (which may be inherently structured though, e.g. spatial sound systems or stereoscopic video)
@ -3563,8 +3647,8 @@ Pipe assets are created automatically by being used and referred. Each [[Timelin
Deleting a Pipe is an advanced operation, because it includes finding and &quot;detaching&quot; all references, otherwise the pipe will leap back into existence immediately. Thus, global pipe entries in the Session and pipe references in [[locating pins|LocatingPin]] within any placement have to be removed, while clips using a given source port will be disabled. {{red{todo: implementation deferred}}}
!using Pipes
there is not much you can do directly with a pipe asset. It is an point of reference, after all. Any connection to some pipe is only temporarily done by a placement in some part of the timeline (&amp;rarr; OutputDesignation), so it isn't stored with the pipe. You can edit the (user visible) description an you can globally disable a pipe asset. The pipe's ID and media stream type of course are fixed, because any connection and referral (via the asset ID) is based on them. Later on, we should provide a {{{rewire(oldPipe, newPipe)}}} to search any ref to the {{{oldPipe}}} and try to rewrite it to use the {{{newPipe}}}, possibly with a new media stream type.
Pipes are integrated with the [[management of defaults|DefaultsManagement]]. For example, any pipe implicitly uses some [[processing pattern|ProcPatt]] &amp;mdash; it may default to the empty pattern. This way, any kind of standard wiring might be applied to the pipes (e.g a fader for audio, similar to the classic mixing consoles). This //is // a global property of the pipe, but &amp;mdash; contrary to the stream type &amp;mdash; this pattern may be switched {{red{really?}}}
there is not much you can do directly with a pipe asset. It is an point of reference, after all. Any connection or routing to a target pipe is done by a placement with a suitable WiringPlug in some part of the timeline (&amp;rarr; OutputDesignation), so it isn't stored with the pipe. You can edit the (user visible) description an you can globally disable a pipe asset. The pipe's ID and media stream type of course are fixed, because any connection and referral (via the asset ID) is based on them. Later on, we should provide a {{{rewire(oldPipe, newPipe)}}} to search any ref to the {{{oldPipe}}} and try to rewrite it to use the {{{newPipe}}}, possibly with a new media stream type.
Pipes are integrated with the [[management of defaults|DefaultsManagement]]. For example, any pipe implicitly uses some [[processing pattern|ProcPatt]] &amp;mdash; it may default to the empty pattern. This way, any kind of standard wiring might be applied to the pipes (e.g a fader for audio, similar to the classic mixing consoles). This //is // a global property of the pipe, but &amp;mdash; contrary to the stream type &amp;mdash; this pattern may be switched {{red{really? -- lots of open questions here as of 11/10}}}
</pre>
</div>
<div title="Placement" modifier="Ichthyostega" modified="200910311753" created="200706220306" tags="Concepts def" changecount="11">
@ -4735,7 +4819,7 @@ On the implementation level, there are some interdependencies to consider betwee
<pre>The session manager is responsible for maintaining session state as a whole and for conducting the session [[lifecycle|SessionLifecycle]]. The session manager API allows for saving, loading, closing and resetting the session. Accessible through the static interface {{{Session::current}}}, it exposes the actual session as a ~PImpl. Actually, both session and session manager are interfaces.
</pre>
</div>
<div title="SessionMutation" modifier="Ichthyostega" modified="201003020143" created="201002170332" tags="SessionLogic spec decision draft" changecount="3">
<div title="SessionMutation" modifier="Ichthyostega" modified="201011210252" created="201002170332" tags="SessionLogic spec decision draft" changecount="5">
<pre>//Any modification of the session will pass through the [[command system|CommandHandling]].//
Thus any possible mutation comes in two flavours: a raw operation invoked directly on an object instance attached to the model, and a command taking an MObjectRef as parameter. The latter approach &amp;mdash; invoking any mutation through a command &amp;mdash; will pass the mutations trough the ProcDispatcher to ensure the're logged for [[UNDO|UndoManager]] and executed sequentially, which is important, because the session's internals are //not threadsafe by design.// Thus we're kind of enforcing the use of Commands: mutating operations include a check for a &amp;raquo;permission to mutate&amp;laquo;, which is automatically available within a command execution {{red{TODO as of 2/10}}}. Moreover, the session API and the corresponding LayerSeparationInterfaces expose MObjectRef instances, not raw (language) refs.
@ -4746,7 +4830,7 @@ Thus any possible mutation comes in two flavours: a raw operation invoked direct
* how to keep [[dependencies within the model|ModelDependencies]] up-to date?
!!who defines commands?
The answer is simple: the one who needs to know about their existence. Because basically commands are invoked //by-name// &amp;mdash; someone needs to be aware of that name and what it denotes. Thus, for any given mutation, there is a place where it's meaningful to specify the details //and// to subsume them under a meaningful term. An entity responsible for this place could then act as the provider of the command in question.
The answer is simple: the one who needs to know about their existence. Because basically commands are invoked //by-name// -- someone needs to be aware of that name and its meaning. Thus, for any given mutation, there is a place where it's meaningful to specify the details //and//&amp;nbsp; to subsume them under a meaningful term. An entity responsible for this place could then act as the provider of the command in question.
Interestingly, there seems to be an alternative answer to this question. We could locate the setup and definition of all commands into a central administrative facility. Everyone in need of a command then ought to know the name and retrieve this command. Sounds like bureaucracy.
</pre>
@ -4934,7 +5018,7 @@ Consequently, as we can't get away with an fixed Enum of all stream prototypes,
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 linear PCM...
</pre>
</div>
<div title="StreamType" modifier="Ichthyostega" modified="201003160202" created="200808060244" tags="spec draft" changecount="16">
<div title="StreamType" modifier="Ichthyostega" modified="201011071741" created="200808060244" tags="spec draft" changecount="21">
<pre>//how to classify and describe media streams//
Media data is supposed 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''.
@ -4949,13 +5033,13 @@ Media data is supposed to appear structured as stream(s) over time. While there
! 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. 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 twist 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
! Lumiera Stream Type handling
!! 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 &amp;mdash; //not necessarily complete// &amp;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, not 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 separating the distinction between various media streams into several levels seems reasonable...
* Each media belongs to a fundamental ''kind'' of media, examples being __Video__, __Image__, __Audio__, __MIDI__,... Media streams of different kind can be considered somewhat &quot;completely separate&quot; &amp;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.
* Each media belongs to a fundamental ''kind'' of media, examples being __Video__, __Image__, __Audio__, __MIDI__, __Text__,... &lt;br/&gt;Media streams of different kind can be considered somewhat &quot;completely separate&quot; &amp;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//&amp;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 &quot;video&quot; and can be converted 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. (&amp;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, but we may as well get 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.
@ -5110,7 +5194,7 @@ Instead, we should try to just connect the various subsystems via Interfaces and
* to shield the rendering code of all complexities of thread communication and synchronization, we use the StateProxy
</pre>
</div>
<div title="StructAsset" modifier="Ichthyostega" modified="201010290143" created="200709221353" tags="def classes img" changecount="19">
<div title="StructAsset" modifier="Ichthyostega" modified="201011060513" created="200709221353" tags="def classes img" changecount="20">
<pre>Structural Assets are intended mainly for internal use, but the user should be able to see and query them. They are not &quot;loaded&quot; or &quot;created&quot; directly, rather they //leap into existence // by creating or extending some other structures in the session, hence the name. Some of the structural Asset parametrisation can be modified to exert control on some aspects of the Proc Layer's (default) behaviour.
* [[Processing Patterns|ProcPatt]] encode information how to set up some parts of the render network to be created automatically: for example, when building a clip, we use the processing pattern how to decode and pre-process the actual media data.
* [[Tracks|Track]] are one of the dimensions used for organizing the session data. They serve as an Anchor to attach parametrisation of output pipe, overlay mode etc. By [[placing|Placement]] to a track, a media object inherits placement properties from this track.
@ -5119,8 +5203,8 @@ Instead, we should try to just connect the various subsystems via Interfaces and
* [[Timeline]] assets are the top level structures to access the model; similar to the sequences, they act as façade to relevant parts of the model (BindingMO) and will be created on demand, alongside with a new session if necessary, bound to the new timeline. Likewise, they can be referred by their name-ID
!naming scheme
The Asset name field of structural Assets utilizes a special naming scheme, which allows to derive the name based on the capabilities of the structural asset. For example, by default all media clips with a given media stream type (e.g. H264) will use the same [[processing Pattern|ProcPatt]] for rendering. {{red{todo: work out the details of this naming scheme??}}}
!querying
Structural assets can be queried by specifying the specific type (Pipe, Track, ProcPatt) and a query goal. For example, you can {{{Query&lt;Pipe&gt; (&quot;stream(mpeg)&quot;)}}}, yielding the first pipe found which declares to have stream type &quot;mpeg&quot;. The access point for this querying facility is on the ~StructFactory, which (as usual within Lumiera) can be invoked as static member {{{Struct::retrieve(Query&lt;TY&gt; ...}}}. Given such a query, first an attempt is made to satisfy it by retrieving an existing object of type TY (which might bind variables as a side effect). On failure, a new structural asset of the requested type will be created to satisfy the given goal. In case you want to bypass the resolution step and create a new asset right away, use {{{Struct::retrieve.newInstance&lt;TY&gt;}}}
@ -6305,13 +6389,14 @@ Thus no server and no network connection is needed. Simply open the file in your
* see [[Homepage|http://tiddlywiki.com]], [[Wiki-Markup|http://tiddlywiki.org/wiki/TiddlyWiki_Markup]]
</pre>
</div>
<div title="Timeline" modifier="Ichthyostega" modified="201010180151" created="200706250721" tags="def" changecount="17">
<div title="Timeline" modifier="Ichthyostega" modified="201011220126" created="200706250721" tags="def" changecount="21">
<pre>Timeline is the top level element within the [[Session (Project)|Session]]. It is visible within a //timeline view// in the GUI and represents the effective (resulting) arrangement of media objects, to be rendered for output or viewed in a Monitor (viewer window). A timeline is comprised of:
* a time axis in abolute time ({{red{WIP 1/10}}}: not clear if this is an entity or just a conceptual definition)
* a PlayControler ({{red{WIP Summer 2010: see discussion on ML. It seems rather that the controller will be attached}}})
* a list of global Pipes representing the possible outputs (master busses)
* a list of [[global Pipes|GlobalPipe]] representing the possible outputs (master busses)
* //exactly one// top-level [[Sequence]], which in turn may contain further nested Sequences.
Please note especially that following this design //a timeline doesn't define tracks.// [[Tracks form a Tree|Track]] and are part of the individual sequences, together with the media objects placed to these tracks.
Please note especially that following this design //a timeline doesn't define tracks.// [[Tracks form a Tree|Track]] and are part of the individual sequences, together with the media objects placed to these tracks. Thus sequences are independent entities which may exist stand-alone within the model, while a timeline is //always bound to hold a sequence.// &amp;rarr; see ModelDependencies
[&gt;img[Fundamental object relations used in the session|uml/fig136453.png]]
Within the Project, there may be ''multiple timelines'', to be viewed and rendered independently. But, being the top-level entities, multiple timelines may not be combined further. You can always just render (or view) one specific timeline. A given sequence may be referred directly or indirectly from multiple timelines though.
@ -6530,19 +6615,27 @@ For now, as of 6/10, we use specialised QueryResolver instances explicitly and d
&amp;rarr; QueryRegistration
</pre>
</div>
<div title="ViewerPlayConnection" modifier="Ichthyostega" created="201007110305" tags="Model Player spec draft" changecount="1">
<div title="ViewerPlayConnection" modifier="Ichthyostega" modified="201011100202" created="201007110305" tags="Model Player spec draft" changecount="6">
<pre>for showing output, three entities are involved
* the [[Timeline]] holds the relevant part of the model, which gets rendered for playback
* by connecting to a viewer component, an actual output target is established
* the playback process itself is coordinated by a PlayController, which in turn creates a PlayProcess
!the viewer connection
A viewer element gets connected to a given timeline either by directly attaching it, or by //allocating an available free viewer.// Anyway, as a model element, the viewer is just like another set of global pipes cascaded behind the global pipes present in the timeline. The number and kind of pipes provided is a configurable property of the viewer element &amp;mdash; more specifically: the viewer's SwitchBoard. Thus, connecting a viewer activates the same internal logic employed when connecting a sequence into a timeline or meta-clip: a default channel association is established, which can be overridden persistently (&amp;rarr; OutputMapping). Each of the viewer's pipes in turn gets connected to a system output through an OutputManager slot &amp;mdash; again an output mapping step.
</pre>
</div>
<div title="VirtualClip" modifier="Ichthyostega" modified="201003130000" created="200804110321" tags="def" changecount="15">
<div title="VirtualClip" modifier="Ichthyostega" modified="201011220152" created="200804110321" tags="def Model" changecount="17">
<pre>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 &quot;real&quot; 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 &quot;embedded&quot; 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 sequence__ is like the other sequences in the Session, just in this case any missing placement properties will be derived from the Virtual Clip, which is thought as to &quot;contain&quot; the objects of the nested sequence. Typically, this also [[configures the tracks|TrackHandling]] of the &quot;inner&quot; sequence such as to connect any output to the source ports of the Virtual Clip.
* a __nested sequence__ is like the other sequences in the Session, just in this case any missing placement properties will be derived from the Virtual Clip, which is thought as to &quot;contain&quot; the objects of the nested sequence. Typically, this also configures the tracks of the &quot;inner&quot; sequence such as to [[connect any output|OutputMapping]] to the source ports of the Virtual Clip.
Like any &quot;real&quot; 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 sequence, 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)
!Implementation
The implementation is based on the observation, that a virtual clip is like a real clip, just referring to a ''virtual media''.
Thus we'll employ a special kind of media asset, which actually links to a [[binding|BindingMO]], which in turn connects to a [[Sequence]]. Its the binding's job to help translating the sequence's contents into a media-like entity, with just //content// apearing in several channels.
{{red{WIP as of 11/2010 -- most details yet to be defined}}}
</pre>
</div>
<div title="VisitingToolImpl" modifier="Ichthyostega" modified="200802031822" created="200801032003" tags="impl excludeMissing" changecount="21">
@ -6625,10 +6718,40 @@ In case it's not already clear: we don't have &quot;the&quot; Render Engine, rat
The &amp;raquo;current setup&amp;laquo; of the objects in the session 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 &quot;stateless&quot; 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).
</pre>
</div>
<div title="Wiring" modifier="Ichthyostega" modified="201009250224" created="201009250223" tags="Concepts Model design draft" changecount="2">
<pre>within Lumiera's Proc-Layer, on the conceptual level there are two kinds of connections: data streams and control connections. The wiring details on how these connections are defined, how they are to be detected by the builder and finally implemented by links in the RenderEngine.
<div title="Wiring" modifier="Ichthyostega" modified="201011090249" created="201009250223" tags="Concepts Model design draft" changecount="30">
<pre>within Lumiera's ~Proc-Layer, on the conceptual level there are two kinds of connections: data streams and control connections. The wiring details on how these connections are defined and controlled, how they are to be detected by the builder and finally implemented by links in the render engine.
&amp;rarr; see OutputManagement
&amp;rarr; see OutputDesignation
&amp;rarr; see OperationPoint
&amp;rarr; see StreamType
!Stream connections
A stream connection should result in media data traveling from a source to a sink. Here we have to distinguish between the high-level view and the situation in the render engine. At the session level and thus for the user, a //stream// is the elementary unit of &quot;media content&quot; flowing through the system. It can be described unambigously by having an uniform StreamType &amp;mdash; this doesn't exclude the stream from being inherently structured, like containing several channels. The HighLevelModel can be interpreted as creating a system of stream connections, which can be categorised as yielding two kinds of connections:
* the [[Pipes|Pipe]] are rather rigid ''processing chains'', limited to using one specific StreamType. Pipes are build by attaching processing descriptors (Effect ~MObjects), where the order of attachment is given by the placement.
* there are flexible interconnections or ''routing links'', including the ability to sum or overlay media streams, and the possibility of stream type conversions. They are controlled by the OutputDesignation (&quot;wiring plug&quot;), to be queried from the placement at the source side of the interconnection (i.e. at the exit point of a pipe)
Please note, the high-level model comprises a blue print for constructing the render engine. There is no data &quot;flowing&quot; through this model, thus any &quot;wiring&quot; may be considered conceptual. Any wiring specifications here just express the intention of getting things connected in a given way. Like e.g. a clip may find out (through query of his placement) that he's intended to produce output for some destination / bus / subgroup called &quot;XYZ&quot;
The builder to the contrary considers matters locally. He's confined to a given set of objects handed in for processing, and during that processing will collect all [[plugs|WiringPlug]] and [[claims|WiringClaim]] encountered. While the former denote the desired //destination//&amp;nbsp; of data emerging from a pipe, the wiring claim expresses the fact that a given object //claims to be some output destination.// Typically, each [[global pipe or bus|GlobalPipe]] raises such a claim. Both plugs and claims are processed on a &quot;just in case they exist&quot; base: When encountering a plug and //resolving//&amp;nbsp; the corresponding claim, the builder drops off a WiringRequest accordingly. Note the additional resolution, which might be necessary due to virtual media and nested sequences (read: the output designation might need to be translated into another designation, using the media/channel mapping created by the virtual entity &amp;rarr; see [[mapping of output designations|OutputMapping]])
Processing the wiring request drives the actual connection step. It is conducted by the OperationPoint, provided by and executing within a BuilderMould and controlled by a [[processing pattern|ProcPatt]]. This rather flexible setup allows for wiring summation lines, include faders, scale and offset changes and various overlay modes. Thus the specific form of the connection wired in here depends on all the local circumstances visible at that point of operation:
* the mould is picked from a small number of alternatives, based on the general wiring situation.
* the processing pattern is queried to fit the mould, the stream type and additional placement specifications ({{red{TODO 11/10: work out details}}})
* the stream type system itself contributes in determining possible connections and conversions, introducing further processing patterns
The final result, within the render engine, is a network of processing nodes. Each of this nodes holds a WiringDescriptor, created as a result of the wiring operation detailed above. This descriptor lists the predecessors, and (in somewhat encoded form) the other details necessary for the processing node to respond properly at the engine's calculation requests (read: those details are implementation bound and can be expeted to be made to fit)
On a more global level, this LowLevelModel within the engine exposes a number of [[exit nodes|ExitNode]], each corresponding to a ModelPort, thus being a possible source to be handled by the OutputManager, which is responsible for mapping and connecting nominal outputs (the model ports) to actual output sinks (external connections and viewer windows). A model port isn't necessarily an absolute endpoint of connected processing nodes &amp;mdash; it may as well reside in the middle of the network, e.g. as a ProbePoint. Besides the core engine network, there is also an [[output network|OutputNetwork]], built and extended on demand to prepare generated data for the purpose of presentation. This ViewerPlayConnection might necesitate scaling or interpolating video for a viewer, adding overlays with control information produced by plugins, or rendering and downmixing multichannel sound. By employing this output network, the same techniques used to control wiring of the main path, can be extended to control this output preparation step. ({{red{WIP 11/20}}} some important details are to be settled here, like how to control semi-automatic adaptation steps. But that is partially true also for the main network: for example, we don't know where to locate and control the faders generated as a consequence of building a summation line)
!!!Participants and Requirements
* the ~Pipe-ID needs to be something easily usable
* output designation is just a ~Pipe-ID, actually a thin wrapper to make the intention explicit
* claims and plugs are to be implemented as LocatingPin
* as decided elsewhere, we get a [[Bus-MObject|BusMO]] as an attachment point
* we need OutputMapping as a new generic interface, allowing us to define ~APIs in terms of mappings
* builder moulds, operation point and processing patterns basically are in place, but need to be shaped
* the actual implementation in the engine will evolve as we go; necessary adaptations are limited to the processing patterns (which is intentional)
!Control connections
</pre>