OutputDesignation implementation draft
This commit is contained in:
parent
cfc4325f55
commit
9473fd3d67
6 changed files with 142 additions and 15 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
74
src/proc/mobject/output-designation.cpp
Normal file
74
src/proc/mobject/output-designation.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
#include "proc/mobject/output-designation.hpp"
|
||||
|
||||
namespace mobject {
|
||||
|
||||
typedef OutputDesignation::PPipe PPipe;
|
||||
typedef OutputDesignation::PID PID;
|
||||
|
||||
|
||||
/** create an output designation by directly
|
||||
* specifying the target to connect
|
||||
*/
|
||||
OutputDesignation::OutputDesignation (PID explicitTarget)
|
||||
: spec_() //////////TODO
|
||||
{ }
|
||||
|
||||
|
||||
/** create an output designation indirectly
|
||||
* to be resolved by forwarding the resolution
|
||||
* to the given reference scope / mediator.
|
||||
*/
|
||||
OutputDesignation::OutputDesignation (RefPlacement const& indirectTarget)
|
||||
: spec_() //////////TODO
|
||||
{ }
|
||||
|
||||
|
||||
/** 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_() //////////TODO
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
PID
|
||||
OutputDesignation::resolve (PPipe origin)
|
||||
{
|
||||
UNIMPLEMENTED ("Forward output designation resolution request to the embedded spec object");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace mobject
|
||||
|
|
@ -25,16 +25,24 @@
|
|||
#define PROC_MOBJECT_OUTPUT_DESIGNATION_H
|
||||
|
||||
#include "proc/asset/pipe.hpp"
|
||||
#include "lib/opaque-holder.hpp"
|
||||
|
||||
|
||||
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 a asset::Pipe by ID. In order to get
|
||||
* 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
|
||||
|
|
@ -45,6 +53,35 @@ namespace mobject {
|
|||
class OutputDesignation
|
||||
{
|
||||
public:
|
||||
typedef asset::ID<asset::Pipe> PID;
|
||||
typedef asset::PPipe PPipe;
|
||||
|
||||
PID resolve (PPipe origin);
|
||||
|
||||
//TODO: API to retrieve target stream type
|
||||
|
||||
|
||||
explicit OutputDesignation (PID explicitTarget);
|
||||
explicit OutputDesignation (RefPlacement const& indirectTarget);
|
||||
explicit OutputDesignation (uint relative_busNr =0);
|
||||
|
||||
// using default copying
|
||||
|
||||
private:
|
||||
|
||||
class TargetSpec
|
||||
{
|
||||
public:
|
||||
virtual ~TargetSpec();
|
||||
PID resolve (PPipe origin);
|
||||
};
|
||||
|
||||
enum{ SPEC_SIZ = sizeof(PID) };
|
||||
typedef lib::OpaqueHolder<TargetSpec, SPEC_SIZ> SpecBuff;
|
||||
|
||||
/** Storage to hold the Target Spec inline */
|
||||
SpecBuff spec_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2005,7 +2005,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]]
|
||||
|
|
@ -2032,19 +2032,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'' &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<T> 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 "resource acquisition is initialisation" (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>
|
||||
|
|
@ -2885,9 +2887,9 @@ The operation point is provided by the current BuilderMould and used by the [[pr
|
|||
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="201011132128" created="201006220126" tags="Model draft design discuss" changecount="44">
|
||||
<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
|
||||
|
|
@ -2922,18 +2924,26 @@ 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 &mdash; additionally &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).
|
||||
&rarr; OutputManagement
|
||||
|
||||
!Mapping of output designations
|
||||
!!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 &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.
|
||||
&rarr; see OutputMapping regarding details and implementation of this mapping mechanism
|
||||
|
||||
|
||||
|
||||
|
||||
!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)
|
||||
|
||||
!Using output designations
|
||||
!!!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 "flow" through the pipes from source to output. This conceptual ("high level") 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// &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 "Plug" (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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue