planning: structural assets and the track-ID
This commit is contained in:
parent
8eb0a16134
commit
8f34129f60
8 changed files with 247 additions and 76 deletions
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "proc/mobject/session.hpp"
|
||||
#include "common/configrules.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -47,6 +48,7 @@ using boost::format;
|
|||
|
||||
using mobject::Session;
|
||||
|
||||
using lib::Symbol;
|
||||
using util::isnil;
|
||||
using util::contains;
|
||||
using asset::Query;
|
||||
|
|
@ -56,26 +58,31 @@ using lumiera::query::extractID;
|
|||
namespace asset {
|
||||
|
||||
|
||||
template<class STRU>
|
||||
struct Traits
|
||||
{
|
||||
static Symbol namePrefix;
|
||||
static Symbol catFolder;
|
||||
static Symbol idSymbol;
|
||||
};
|
||||
|
||||
template<> Symbol Traits<Track>::namePrefix = "track";
|
||||
template<> Symbol Traits<Track>::catFolder = "tracks";
|
||||
template<> Symbol Traits<Track>::idSymbol = "track";
|
||||
|
||||
template<> Symbol Traits<Pipe>::namePrefix = "pipe";
|
||||
template<> Symbol Traits<Pipe>::catFolder = "pipes";
|
||||
template<> Symbol Traits<Pipe>::idSymbol = "pipe";
|
||||
|
||||
template<> Symbol Traits<const ProcPatt>::namePrefix = "patt";
|
||||
template<> Symbol Traits<const ProcPatt>::catFolder = "build-templates";
|
||||
template<> Symbol Traits<const ProcPatt>::idSymbol = "procPatt";
|
||||
|
||||
namespace { // structural asset ID scheme ///////////////////////////////////////////////////////////TICKET #565
|
||||
|
||||
template<class STRU>
|
||||
struct Traits
|
||||
{
|
||||
static Symbol namePrefix;
|
||||
static Symbol catFolder;
|
||||
static Symbol idSymbol;
|
||||
};
|
||||
|
||||
template<> Symbol Traits<Track>::namePrefix = "track";
|
||||
template<> Symbol Traits<Track>::catFolder = "tracks";
|
||||
template<> Symbol Traits<Track>::idSymbol = "track";
|
||||
|
||||
template<> Symbol Traits<Pipe>::namePrefix = "pipe";
|
||||
template<> Symbol Traits<Pipe>::catFolder = "pipes";
|
||||
template<> Symbol Traits<Pipe>::idSymbol = "pipe";
|
||||
|
||||
template<> Symbol Traits<const ProcPatt>::namePrefix = "patt";
|
||||
template<> Symbol Traits<const ProcPatt>::catFolder = "build-templates";
|
||||
template<> Symbol Traits<const ProcPatt>::idSymbol = "procPatt";
|
||||
|
||||
Symbol genericIdSymbol ("id");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -94,8 +101,12 @@ namespace asset {
|
|||
const Asset::Ident
|
||||
createIdent (const Query<STRU>& query)
|
||||
{
|
||||
string name (query);
|
||||
string nameID = extractID (Traits<STRU>::idSymbol, query);
|
||||
string name (query);
|
||||
|
||||
// does the query somehow specify the desired name-ID?
|
||||
string nameID = extractID (genericIdSymbol, query);
|
||||
if (isnil (nameID))
|
||||
nameID = extractID (Traits<STRU>::idSymbol, query);
|
||||
if (isnil (nameID))
|
||||
{
|
||||
// no name-ID contained in the query...
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "proc/asset/struct-factory-impl.hpp"
|
||||
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "include/logging.h"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
|
@ -83,7 +84,7 @@ namespace asset {
|
|||
/** Factory method for Structural Asset instances.
|
||||
* First tries to resolve the asset by issuing an capability query.
|
||||
* If unsuccessful, use some internally specialised ctor call.
|
||||
* @todo work out the struct asset naming scheme!
|
||||
* @todo work out the struct asset naming scheme! /////////////////////////////////TICKET #565
|
||||
* @todo for now we're using a faked config query, just pulling preconfigured
|
||||
* hardwired answers from a table. Should be replaced by a real resolution engine.
|
||||
* @return an Struct smart ptr linked to the internally registered smart ptr
|
||||
|
|
|
|||
|
|
@ -24,11 +24,31 @@
|
|||
/** @file struct.hpp
|
||||
** Structural parts of the Session (e.g. Tracks) can be reflected
|
||||
** into the "bookkeeping view" as a specific Kind of Asset.
|
||||
** For the different <i>Kinds</i> of Assets, we use sub-interfaces inheriting
|
||||
** from the general Asset interface. To be able to get asset::Struct instances
|
||||
** directly from the AssetManager, we define a specialisation of the Asset ID.
|
||||
**
|
||||
** @see asset.hpp for explanation
|
||||
** For the different \em kinds of Assets, we use sub-interfaces inheriting
|
||||
** from the general Asset interface, each of which expose a distinguishing feature.
|
||||
** In the case of structural assets, the key point is a naming scheme allowing for
|
||||
** retrieval of instances with specific capabilities; structural assets are created
|
||||
** on demand, just by referral. Thus, the collection of these assets provides a map
|
||||
** for exploring the current session's structure and allow for tweaking of the
|
||||
** default behaviour.
|
||||
** - Track acts as unique track ID
|
||||
** - Timeline and Sequence are facades, part of the session API
|
||||
** - Pipe is an attachment point for wiring connections and defines a StreamType
|
||||
** - ProcPatt is used as a blueprint in the build process, a standard connection pattern
|
||||
**
|
||||
** \par access and creation
|
||||
** asset::Struct instances are created on demand; the interface is to invoke the
|
||||
** StructFactory with a (typed) Query describing properties or capabilities.
|
||||
** In case this query succeeds, an existing asset will be returned, otherwise
|
||||
** a suitable new instance is created automatically. Typically, structural assets
|
||||
** aren't deleted. Doing so would require a dedicated function which not only drops
|
||||
** an asset instance from AssetManager, but also ensures removal of all properties
|
||||
** within the model which could cause automatic re-creation of this asset. E.g.
|
||||
** purging a track asset (=unique trackID) requires removing or disconnecting
|
||||
** all placements referring to this track, which could be sub tracks, clips,
|
||||
** effects, automation or labels.
|
||||
**
|
||||
** @see asset.hpp for explanation regarding asset IDs
|
||||
** @see StructFactory creating concrete asset::Struct instances
|
||||
**
|
||||
*/
|
||||
|
|
@ -74,7 +94,12 @@ namespace asset {
|
|||
|
||||
/**
|
||||
* key abstraction: structural asset
|
||||
* @todo just a stub, have to figure out what a asset::Struct is
|
||||
* Created automatically as a sideeffect of building the structure
|
||||
* of the high-level-model (session contents), thus providing IDs
|
||||
* for later referral, search and attachment of metadata.
|
||||
*
|
||||
* Examples being tracks, sequences, timelines, pipes, processing patterns
|
||||
*
|
||||
* @todo WIP as of 1/2010. Need to integrate Sequences and Timelines
|
||||
*/
|
||||
class Struct : public Asset
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@
|
|||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
|
||||
namespace asset {
|
||||
|
||||
|
||||
/**
|
||||
* Structural Asset using as a global identifier for placing
|
||||
* some object onto a given track. Not to be confused with the "track-MO":
|
||||
* To actually use a track within an Sequence, we need to attach a
|
||||
* Structural Asset used as a global identifier for placing
|
||||
* media objects onto a given track. Not to be confused with the "track-MO",
|
||||
* the MObject which becomes part of the high-level-model:
|
||||
* In order actually to use a track within an Sequence, we need to attach a
|
||||
* Placement<mobject::session::Track> to the tree-of-tracks of this Sequence.
|
||||
* Thus, we have one global track-identifier (this class here), but
|
||||
* maybe several instances (track-MO) within various Sequences
|
||||
* Thus, we have one global track-identifier (this class here), but maybe
|
||||
* several instances (placement of a track-MO) within various Sequences
|
||||
*/
|
||||
class Track : public Struct
|
||||
{
|
||||
|
|
@ -49,8 +49,8 @@ namespace asset
|
|||
|
||||
|
||||
typedef P<const Track> PTrack;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,28 +24,27 @@
|
|||
#include "proc/mobject/session/track.hpp"
|
||||
#include "proc/asset/track.hpp"
|
||||
|
||||
namespace mobject
|
||||
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
|
||||
/** new track-MO linked with the given asset::Track.
|
||||
* Initially, the reference (zero-point) time of this track
|
||||
* will be set to 0
|
||||
*/
|
||||
Track::Track (PTrackAsset& trackDef)
|
||||
: start_(0),
|
||||
trackDef_(trackDef)
|
||||
{ }
|
||||
|
||||
|
||||
bool
|
||||
Track::isValid() const
|
||||
{
|
||||
namespace session
|
||||
{
|
||||
|
||||
/** new track-MO linked with the given asset::Track.
|
||||
* Initially, the reference (zero-point) time of this track
|
||||
* will be set to 0
|
||||
*/
|
||||
Track::Track (PTrackAsset& trackDef)
|
||||
: start_(0),
|
||||
trackDef_(trackDef)
|
||||
{ }
|
||||
|
||||
|
||||
bool
|
||||
Track::isValid() const
|
||||
{
|
||||
TODO ("sensible Track-MO self-check");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mobject::session
|
||||
|
||||
} // namespace mobject
|
||||
TODO ("sensible Track-MO self-check");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace mobject::session
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace session {
|
|||
* matching track-MO for the Sequence in question. If the Session contains several instances
|
||||
* (track-MO) referring to the same trackID (asset), then this causes all objects placed
|
||||
* onto this track to be included several times in the resulting render nodes network
|
||||
* (possibly with varying placement properties)
|
||||
* (possibly with varying placement properties) //////////////TODO 3/2010 likely *not* implementing this feature, because we have sequences
|
||||
*/
|
||||
class Track : public Meta
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
SessionModifyParts(Test) - adding and removing elements, changing structure
|
||||
|
||||
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 "proc/mobject/session.hpp"
|
||||
#include "proc/mobject/session/fixture.hpp" // TODO only temporarily needed
|
||||
//#include "proc/assetmanager.hpp" //////??
|
||||
//#include "proc/asset/timeline.hpp"
|
||||
#include "proc/asset/sequence.hpp"
|
||||
//#include "lib/lumitime.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using util::isSameObject;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
// using proc_interface::AssetManager;
|
||||
using proc_interface::PAsset;
|
||||
|
||||
// using asset::PTimeline;
|
||||
using asset::PSequence;
|
||||
using asset::RTrack;
|
||||
|
||||
// using lumiera::Time;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* @test access the current session and verify the correct
|
||||
* structure of the most important components: The session
|
||||
* contains an Sequence, we can get at the Fixture, we have at least
|
||||
* one Track and the corresponding Track asset is available.
|
||||
* @todo define further criteria to be checked
|
||||
* @todo implement Sequence, Fixture, Session#rebuildFixture, asset::Track
|
||||
*/
|
||||
class SessionModifyParts_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
Session::current.reset();
|
||||
CHECK (Session::current.isUp());
|
||||
|
||||
addTracks();
|
||||
removeParts();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addTracks()
|
||||
{
|
||||
|
||||
PSess sess = Session::current;
|
||||
CHECK (sess->isValid());
|
||||
|
||||
PSequence seq = sess->defaults (Query<Sequence> ()); //////////////////////TICKET #549
|
||||
CHECK (seq);
|
||||
|
||||
RTrack track1 = seq->attachTrack();
|
||||
RTrack track2 = seq->attachTrack("track-2");
|
||||
RTrack track21 = seq->attachTrack("track-2.1", track2);
|
||||
RTrack track22 = seq->attachTrack("track-2.2", "track-2");
|
||||
|
||||
QueryFocus& focus = sess->focus();
|
||||
CHECK (track22 == focus.getObject());
|
||||
|
||||
RTrack track3 = seq->attachTrack("track-3", "root");
|
||||
CHECK (track3 == focus.getObject());
|
||||
|
||||
RTrack track31 = sess->attach()
|
||||
|
||||
CHECK (isSameObject (seq, til->getSequence()));
|
||||
|
||||
//verify default timeline
|
||||
Axis& axis = til->getAxis();
|
||||
CHECK (Time(0) == axis.origin());
|
||||
CHECK (Time(0) == til->length()); ////////////////////////TICKET #177
|
||||
|
||||
//verify global pipes
|
||||
//TODO
|
||||
|
||||
//verify default sequence
|
||||
Track rootTrack = seq->rootTrack();
|
||||
CHECK (rootTrack->isValid());
|
||||
CHECK (Time(0) == rootTrack->length());
|
||||
CHECK (0 == rootTrack->subTracks.size());
|
||||
CHECK (0 == rootTrack->clips.size());
|
||||
//TODO verify the output slots of the sequence
|
||||
|
||||
//TODO now use the generic query API to discover the same structure.
|
||||
CHECK (til == *(sess->all<Timeline>()));
|
||||
CHECK (seq == *(sess->all<Sequence>()));
|
||||
CHECK (rootTrack == *(sess->all<Track>()));
|
||||
CHECK (! sess->all<Clip>());
|
||||
|
||||
QueryFocus& focus = sess->focus();
|
||||
CHECK (rootTrack == focus.getObject());
|
||||
focus.navigate (til);
|
||||
CHECK (til.getBinding() == focus.getObject());
|
||||
CHECK (rootTrack == *(focus.children()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (SessionModifyParts_test, "unit session");
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
@ -2320,7 +2320,7 @@ For the case here in question this seems to be the ''resource allocation is cons
|
|||
And, last but not least, doing large scale allocations is the job of the backend. Exceptions being long-lived objects, like the session or the sequences, which are created once and don't bear the danger of causing memory pressure. Besides, the ProcLayer code shouldn't issue "new" and "delete" when it comes in hand, rather it should use some centralized [[Factories]] for all allocation and freeing, so we can redirect these calls down to the backend, which may use pooling or special placement allocators or the like. The rationale is, for modern hardware/architectures, care has to be taken with heap allocations, esp. with many small objects and irregular usage patterns.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ModelDependencies" modifier="Ichthyostega" modified="201003020510" created="201003020150" tags="SessionLogic spec dynamic draft" changecount="22">
|
||||
<div title="ModelDependencies" modifier="Ichthyostega" modified="201003060012" created="201003020150" tags="SessionLogic spec dynamic draft" changecount="23">
|
||||
<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, mainly due to the fact of keeping the session implementation mostly single-threaded. Thus, care has to be taken to capture and treat all the relevant dependencies properly at the implementation level.
|
||||
|
||||
!known interdependencies
|
||||
|
|
@ -2339,7 +2339,7 @@ While implemented as StructAsset, additionally we need to assure every instance
|
|||
;Timeline
|
||||
:acts as facade and is implemented by an BindingMO, which can't exist in isolation.
|
||||
: __created__ &rArr; create new binding, use either newly created (maybe default) sequence, or use existing sequence
|
||||
: __destroy__ &rArr; remove binding, while the bound sequence remains in model.
|
||||
: __destroy__ &rArr; remove binding, while the previously bound sequence remains in model.
|
||||
;Binding
|
||||
:is completely dependent and can't even be created without prerequisites
|
||||
: __created__ &rArr; mandates specification of a timeline, while the sequence is optional and will be created if missing
|
||||
|
|
@ -3520,13 +3520,11 @@ Besides, they provide an __inward interface__ for the [[ProcNode]]s, enabling th
|
|||
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ProcLayer and Engine" modifier="Ichthyostega" modified="200910311726" created="200706190056" tags="overview" changecount="26">
|
||||
<div title="ProcLayer and Engine" modifier="Ichthyostega" modified="201003042333" created="200706190056" tags="overview" changecount="27">
|
||||
<pre>The Render Engine is the part of the application doing the actual video calculations. Utilising system level services and retrieving raw audio and video data through [[Lumiera's Backend|backend.html]], its operations are guided by the objects and parameters edited by the user in [[the session|Session]]. Thus, the Lumiera Proc-Layer covers the (abstract) edit operations available to the user, the representation of [["editable things"|MObjects]] and the translation of those into facilities allowing to [[drive the rendering|Rendering]].
|
||||
<<<
|
||||
''Status'': started out as design draft in summer '07, Ichthyo is now in the middle of a implementing the foundations and main structures in C++
|
||||
* basic [[AssetManager]] working
|
||||
* [[Builder]] implementation is on the way (&rarr;[[more|BuilderPrimitives]])
|
||||
* made a first draft of how to wire and operate processing nodes (&rarr;[[more|RenderMechanics]])
|
||||
* first attempts to [[integrate with the GUI|GuiIntegration]]
|
||||
* first outline of the [[session implementation|PlanningSessionInMem]]
|
||||
* as a prerequisite, defined and implemented [[Proc-Layer Command frontend|CommandHandling]]
|
||||
|
|
@ -4151,7 +4149,7 @@ The session and the models rely on dependent objects beeing kept updated and con
|
|||
&rarr; see [[details here...|ModelDependencies]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SessionInterface" modifier="Ichthyostega" modified="201002210435" created="200904242108" tags="SessionLogic GuiIntegration design draft discuss" changecount="35">
|
||||
<div title="SessionInterface" modifier="Ichthyostega" modified="201003042334" created="200904242108" tags="SessionLogic GuiIntegration design draft discuss" changecount="36">
|
||||
<pre>"Session Interface", when used in a more general sense, denotes a compound of several interfaces and facilities, together forming the primary access point to the user visible contents and state of the editing project.
|
||||
* the API of the session class
|
||||
* the accompanying management interface (SessionManager API)
|
||||
|
|
@ -4202,7 +4200,7 @@ While this protects against accessing dangling references, it can't prevent clie
|
|||
The considered solution would be to treat this situation as if an authorisation is required; this authorisation for mutation could be checked by a &raquo;wormhole&laqou;-like context access. Of course, in our case we're not dealing with real access restrictions, just a safeguard: While command execution creates such an authorisation token automatically, a client actually wanting to invoke an mutation operations bypassing the command frontend, would need to set up such a token explicitly and manually.
|
||||
|
||||
!!!adding and destroying
|
||||
Objects can be added and destroyed directly on the top level session API. The actual memory management of the object instances works automatically, based on reference counts. (Even after destroying an object, it may still be indirectly in use by an ongoing render process).
|
||||
Objects can be added and destroyed directly on the top level session API. The actual memory management of the object instances works automatically, based on reference counts. (Even after purging an object from the session, it may still be indirectly in use by an ongoing render process).
|
||||
When adding an object, a [[scope|PlacementScope]] needs to be specified. Thus it makes sense to provide the {{{add()}}}-operation on the dedicated API of individual session parts, while the generic {{{add()}}}-call on the top-level session API relies on the current QueryFocus to determine the location where to add an object. Besides, as we're always adding the [[Placement]] of an object into the session, this placement may specify an additional constraint or tie to a specific scope; resolving the placement thus may cause the object to move to another location
|
||||
|
||||
|
||||
|
|
@ -5888,18 +5886,19 @@ Of course, we can place other ~MObjects relative to some track (that's the main
|
|||
&rarr; [[Anatomy of the high-level model|HighLevelModel]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TrackHandling" modifier="Ichthyostega" modified="200912080302" created="200804110013" tags="spec" changecount="24">
|
||||
<div title="TrackHandling" modifier="Ichthyostega" modified="201003050315" created="200804110013" tags="spec" changecount="32">
|
||||
<pre>What //exactly&nbsp;// is denoted by &raquo;Track&laquo; &mdash; //basically&nbsp;// a working area to group media objects placed at this track at various time positions &mdash; varies depending on context:
|
||||
* viewed as [[structural asset|StructAsset]], tracks are nothing but global identifiers (possibly with attached tags and description)
|
||||
* regarding the structure //within each [[Sequence]],// tracks form a tree-like grid, the individual track being attached to this tree by a [[Placement]], thus setting up properties of placement (time reference origin, output connection, layer, pan) which will be inherited down to any objects located on this track and on child tracks, if not overridden more locally.
|
||||
* with respect to //object identity,// a given track-ID can have an incarnation or manifestation as real track-object within several [[sequences|Sequence]] (meaning you could select, disable or choose for rendering all objects in any sequence placed onto this track). Moreover, the track-//object// and the //placement&nbsp;// of this track within the tree of tracks of a given sequence are two distinguishable entities (meaning a given track &mdash; with a couple of objects located on it &mdash; could be placed differently several times within the same sequence {{red{really??}}}, for example with different start offset or with different layering, output mode or pan position)
|
||||
{{red{3/2010: no!}}} &mdash; it doesn't work this way. Relative placements attach to other placements, not ~MObjects. Thuse the clips in this example are within the scope of //one// placement. We could create //another// placement of the same track and attach it to to a differenc sequence, but this other placement wouldn't "inherit" the clips attached to the first one!
|
||||
|
||||
!Identification
|
||||
Tracks thus represent a blend of several concepts, but depending on the context it is allways clear which aspect is meant. Seen as [[assets|Asset]], tracks are known by a unique track-ID, which can be either [[queried|ConfigQuery]], or directly refered to by use of the asset-ID (which is a globally known hash). Usually, all referrals are via track-ID, including when you [[place|Placement]] an object onto a track.
|
||||
Under some cincumstances though, especially from within the [[Builder]], we refer to a {{{Placement<Track>}}} rather, denoting a specific instantiation located at a distinct node within the tree of tracks of a given sequence. These latter referrals are always done by direct object reference, e.g. while traversing the track tree (generally there is no way to refer to a placement by name).
|
||||
Under some cincumstances though, especially from within the [[Builder]], we refer to a {{{Placement<Track>}}} rather, denoting a specific instantiation located at a distinct node within the tree of tracks of a given sequence. These latter referrals are always done by direct object reference, e.g. while traversing the track tree (generally there is no way to refer to a placement by name {{red{Note 3/2010 meanwhile we have placementIDs and we have ~MObjectRef. TODO better wording}}}).
|
||||
|
||||
!creating tracks
|
||||
Similar to [[pipes|Pipe]] and [[processing patterns|ProcPatt]], track-assets need not be created, but rather leap into existence on first referral. On the contrary, you need to explicitly create the {{{Placement<Track>}}} for attaching it to some node within the tree of tracks of an sequence. The public access point for creating such a placement is {{{asset::Struct::create(trackID}}} (i.e. the {{{asset::StructFactory}}}), which, as a convenience shortcut, can also be accessed from the interface of the track-objects within the sequence for adding new child tracks to a given track.
|
||||
Similar to [[pipes|Pipe]] and [[processing patterns|ProcPatt]], track-assets need not be created, but rather leap into existence on first referral. On the contrary, you need to explicitly create the {{{Placement<Track>}}} for attaching it to some node within the tree of tracks of an sequence. The public access point for creating such a placement is {{{asset::Struct::create(trackID}}} (i.e. the {{{asset::StructFactory}}}), which, as a convenience shortcut, can also be accessed from the interface of the track-objects within the sequence for adding new child tracks to a given track.{{red{TODO 3/2010: not quite, the latter is an abstraction built on top. It //delegates// to the ~StructFactory internally, but also wraps into Command}}}
|
||||
|
||||
!removal
|
||||
Deleting a Track is an operation with drastic consequences, as it will cause the removal of all child tracks and the deletion of //all object placements to this track,// which could cause the resepctive objects to go out of scope (being deleted automatically by the placements or other smart pointer classes in charge of them). On the contrary, removing a {{{Placement<Track>}}} from the tree of tracks of an sequence will just cause all objects placed onto this track to disappear (because they are no longer reachable for the build process). On re-adding it, they will show up again. (This is how things behave based on how we defined the relations of the entities to be. Another question is if we want to make this functionality available to the user. Judging from the use of Ardour's &laquo;Playlists&raquo;, such a feature may be quite helpful).
|
||||
|
|
|
|||
Loading…
Reference in a new issue