From 06f2503e6235b53b63e5dabb1d02e4139692d823 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 10 Oct 2007 03:54:09 +0200 Subject: [PATCH 01/22] clarified how to handle Placements --- doc/devel/uml/class128517.html | 3 +- doc/devel/uml/class128645.html | 6 ++-- doc/devel/uml/fig128133.png | Bin 62896 -> 62232 bytes doc/devel/uml/index.html | 11 +----- doc/devel/uml/index_69.html | 4 +-- doc/devel/uml/index_80.html | 1 - doc/devel/uml/index_83.html | 2 +- uml/cinelerra3/128133 | 2 +- uml/cinelerra3/128133.diagram | 10 +++--- uml/cinelerra3/128261 | 29 ++++++--------- uml/cinelerra3/5.session | 10 +++--- uml/cinelerra3/cinelerra3.prj | 2 +- wiki/renderengine.html | 62 ++++++++++++++++++++++----------- 13 files changed, 73 insertions(+), 69 deletions(-) diff --git a/doc/devel/uml/class128517.html b/doc/devel/uml/class128517.html index 31e491fce..f82e4009d 100644 --- a/doc/devel/uml/class128517.html +++ b/doc/devel/uml/class128517.html @@ -20,8 +20,7 @@

Artifact : mobject, Component(s) : Session

Attribut length
-

Declaration :

TODO: how to represent time intervals?

-
Relation placement (<association>)

Declaration :

+

Declaration :

TODO: how to represent time intervals?

All public operations : apply

diff --git a/doc/devel/uml/class128645.html b/doc/devel/uml/class128645.html index b87a32e2c..88a24bf13 100644 --- a/doc/devel/uml/class128645.html +++ b/doc/devel/uml/class128645.html @@ -18,9 +18,9 @@

Declaration :

Directly inherited by : Allocation ExplicitPlacement FixedPlacement RelativePlacement

Artifact : placement

- -
Relation subject (<association>)

Declaration :

-
Operation resolve

Declaration :

create an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements.

+ +
Operation resolve

Declaration :

create an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements.

+
Relation subject (<unidirectional association>)

Declaration :

Placement acts as smart pointer

All public operations : resolve

diff --git a/doc/devel/uml/fig128133.png b/doc/devel/uml/fig128133.png index 70b2dd611e876bb913d0eae72efa619db9a2176c..7a51ef88d6c0ebbcf5bf2eb214a92a95e6a196cd 100644 GIT binary patch literal 62232 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%0AAQJB#4nEawA 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 A<^TWy literal 62896 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 diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index 95d9a7166..dc0e8f165 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -112,7 +112,7 @@ Documentation
Artifact Cinelerra3

Depends on common

Depends on gui

Depends on proc

Depends on backend

the main executable to be built

-

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

+

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

Artifact main

Artifact source

@@ -905,34 +905,25 @@ reuse exiting Engine

Selection :

    Transformation
    Class instance vid_A

    type :Clip

    attributes :

    relations :

    Class instance

    type :RelativePlacement

    attributes :

    relations :

    Class instance

    type :Effect

    attributes :

    relations :

    Class instance

    type :RelativePlacement

    attributes :

    relations :

    Class instance

    type :Effect

    attributes :

    relations :

    Class instance

    type :ExplicitPlacement

    attributes :

    • time = 5
    • diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 20380e20a..0c7bddcba 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,14 +18,14 @@ - + - + diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index d7038cb97..20ee4971b 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -26,7 +26,6 @@ - diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index 847982657..5c1a18530 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -62,7 +62,7 @@ - +
      NameKindDescription
      edlartifactthe (high level) Edit Decision List within the current Session
      EDLcomponent
      EDLclass
      EDLcomponent
      EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
      EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
      edlsrelation
      EffectclassEffect or media processing component
      effectartifactEDL representation of a pluggable and automatable effect.
      effectartifactEffect or media processing component
      effectartifactEDL representation of a pluggable and automatable effect.
      Effectclass
      elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
      enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
      PathManagerclassWhile building a render engine, this Strategy class decides on the actual render strategy in accordance to the current controller settings (system state)
      pathmanagerartifactManager for deciding the actual render strategy
      placementartifactKey Abstraction: a way to place and locate a Media Object
      placementrelation
      Placementclass
      playoperationTODO: will probably be handled differently (see Cehteh)
      playlistnode
      Structclasskey abstraction: structural asset
      structartifactkey abstraction: structural asset
      Struct-Asset Relationsclass diagram
      subjectrelation
      subjectrelationPlacement acts as smart pointer
      subPatternrelation
      diff --git a/uml/cinelerra3/128133 b/uml/cinelerra3/128133 index 83eaacc4c..8438588b6 100644 --- a/uml/cinelerra3/128133 +++ b/uml/cinelerra3/128133 @@ -1,6 +1,6 @@ format 40 "Asset" // ProcessingLayer::Asset - revision 13 + revision 14 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/cinelerra3/128133.diagram b/uml/cinelerra3/128133.diagram index c0272f7ed..a1d67d92a 100644 --- a/uml/cinelerra3/128133.diagram +++ b/uml/cinelerra3/128133.diagram @@ -122,10 +122,6 @@ relationcanvas 129157 relation_ref 128389 // line 129285 z 1999 to ref 129029 role_a_pos 338 687 3000 no_role_b multiplicity_a_pos 314 687 3000 no_multiplicity_b -relationcanvas 129797 relation_ref 128645 // - from ref 129413 z 1999 stereotype "<>" xyz 471 143 3000 to ref 129669 - role_a_pos 513 144 3000 role_b_pos 404 145 3000 - multiplicity_a_pos 547 177 3000 multiplicity_b_pos 393 145 3000 relationcanvas 130181 relation_ref 129029 // geometry HV from ref 128261 z 1999 stereotype "<>" xyz 334 914 3000 to point 339 931 @@ -163,7 +159,7 @@ relationcanvas 132485 relation_ref 129797 // relationcanvas 132997 relation_ref 129925 // from ref 132869 z 1999 to point 529 240 line 133893 z 1999 to ref 129413 - role_a_pos 439 215 3000 no_role_b + role_a_pos 413 204 3000 no_role_b multiplicity_a_pos 401 197 3000 multiplicity_b_pos 515 251 3000 relationcanvas 134533 relation_ref 130309 // from ref 134405 z 1999 to ref 131973 @@ -229,4 +225,8 @@ relationcanvas 139781 relation_ref 142853 // line 139909 z 1999 to ref 139653 role_a_pos 152 426 3000 no_role_b multiplicity_a_pos 126 426 3000 no_multiplicity_b +relationcanvas 140165 relation_ref 142981 // + from ref 129669 z 1999 to ref 129413 + role_a_pos 413 146 3000 no_role_b + multiplicity_a_pos 403 146 3000 multiplicity_b_pos 547 148 3000 end diff --git a/uml/cinelerra3/128261 b/uml/cinelerra3/128261 index 48dbcaf73..60051e702 100644 --- a/uml/cinelerra3/128261 +++ b/uml/cinelerra3/128261 @@ -1,6 +1,6 @@ format 40 "MObject" // ProcessingLayer::MObject - revision 22 + revision 23 modified_by 5 "hiv" // class settings //class diagram settings @@ -409,19 +409,6 @@ ${members}}; comment "TODO: how to represent time intervals?" end - classrelation 129029 // placement () - relation 128645 ---- - stereotype "list" - a role_name "placement" multiplicity "1..*" protected - cpp default " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type} *> ${name}${value}; -" - classrelation_ref 129029 // placement () - b role_name "subject" multiplicity "1" protected - cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; -" - classrelation_ref 129157 // subject () - end - classrelation 137093 // relation 135557 ---|> a public @@ -446,10 +433,6 @@ ${members}}; " explicit_switch_type "" - classrelation 129157 // subject () - relation_ref 128645 // - end - operation 128005 "resolve" public explicit_return_type "ExplicitPlacement [ProcessingLayer::MObject]&" nparams 0 @@ -465,6 +448,16 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} comment "create an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements." end + + classrelation 144901 // subject () + relation 142981 ---> + a role_name "subject" multiplicity "1" protected + comment "Placement acts as smart pointer" + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 144901 // subject () + b multiplicity "1..*" parent class_ref 128517 // MObject + end end class 129797 "ExplicitPlacement" diff --git a/uml/cinelerra3/5.session b/uml/cinelerra3/5.session index 6811c0673..517123540 100644 --- a/uml/cinelerra3/5.session +++ b/uml/cinelerra3/5.session @@ -3,20 +3,20 @@ diagrams classdiagram_ref 130309 // Asset Kinds 860 633 100 4 0 0 active classdiagram_ref 128133 // Session structure - 860 633 100 4 120 0 + 860 633 100 4 47 0 classdiagram_ref 130437 // Media-Asset Relations 860 633 100 4 0 0 classdiagram_ref 128389 // Render Entities 688 506 100 4 120 0 end show_stereotypes -selected - package_ref 129 // cinelerra3 +selected operation_ref 128005 // resolve open - package_ref 128005 // design +package_ref 128005 // design classview_ref 128901 // Assets - class_ref 139781 // SessManager + class_ref 128645 // Placement classview_ref 129029 // Interface + usecaseview_ref 128133 // usage end end diff --git a/uml/cinelerra3/cinelerra3.prj b/uml/cinelerra3/cinelerra3.prj index 48d706651..4680e3711 100644 --- a/uml/cinelerra3/cinelerra3.prj +++ b/uml/cinelerra3/cinelerra3.prj @@ -1,6 +1,6 @@ format 40 "cinelerra3" - revision 31 + revision 32 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 294dda752..44e8ba1d4 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -514,7 +514,7 @@ ColorPalette SiteUrl -
      +
      Asset management is a subsystem on its own. Assets are "things" that can be loaded into a session, like Media, Clips, Effects, Transitions. It is the "bookkeeping view", while the EDL is the "manipulation and process view". Some Assets can be //loaded// and a collection of Assets is saved with eatch Session. Besides, there is a collection of basic Assets allways available by default.
       
       The Assets are important reference points holding the information needed to access external resources. For example, an Clip asset can reference a Media asset, which in turn holds the external filename from which to get the media stream. For Effects, the situation is similar. Assets thus serve two quite distinct purposes. One is to load, list, group search and browse them, and to provide an entry point to create new or get at existing MObjects in the EDL, while the other purpose is to provide attribute and property informations to the inner parts of the engine, while at the same time isolating and decoupling them from environmental details. 
      @@ -524,7 +524,7 @@ We can distinguish several different Kinds of Assets, each one with specific pro
       [img[Asset Classess|uml/fig130309.png]]
       
       !Media Asset
      -Some piece of Media Data accessible at some external Location an able to be processed by Cinelerra. A Media File on Harddisk can be considered as the most basic form of Media Asset, with some important derived Flavours, like a Placeholder for a currently unavailable Source, or Media available in different Resolutions or Formats.
      +Some piece of Media Data accessible at some external Location and able to be processed by Cinelerra. A Media File on Harddisk can be considered as the most basic form of Media Asset, with some important derived flavours, like a Placeholder for a currently unavailable Source, or Media available in different Resolutions or Formats.
       * __outward interface operations__ include querying properties, creating an Clip MObject, controlling processing policy (low res proxy placeholders, interlacing and other generic pre- and postprocessing)
       * __inward interface operations__ include querying filename, codec, offset and any other informations necessary for creating a source render node, getting additional processing policy decisions (handling of interlacing, aspect ratio).
       &rarr; MediaAsset
      @@ -548,9 +548,12 @@ Some additional, virtual facilities created in the course of the editing process
       &rarr; MetaAsset {{red{to be defined}}}
       
       !!!!still to be worked out..
      -is how to implement the relationship between [[MObject]]s and Assets. Do we use direct pointers, or do we prefer an ID + central registry approach? And how to handle the removal of an Asset 
      +is how to implement the relationship between [[MObject]]s and Assets. Do we use direct pointers, or do we prefer an ID + central registry approach? And how to handle the removal of an Asset.
       &rarr; see also [[analysis of mem management|ManagementAssetRelation]]
       &rarr; see also [[Creating Objects|ObjectCreation]], especially [[Assets|AssetCreation]]
      +
      +  //9/07: currently implementing it as follows: use a refcounting-ptr from Clip-~MObject to asset::Media while maintaining a dependency network between Asset objects. We'll see if this approach is viable//
      +
       
      @@ -770,7 +773,7 @@ Cinelerra uses this term in a related manner but with a somewhat shifted focus ( In this usage, the EDL in most cases will be almost synonymous to the [[Session|SessionOverview]], just the latter emphasizes more the state aspect, as it can be thought as the current EDL contents contained in a file or data structure together with additional Option values and settings for the GUI. The Session is what you save and load, while the EDL rather denotes a structured collection of Objects placed in time.
      -
      +
      These are the tools provided to any client of the Proc layer for handling and manipulating the entities in the EDL. When defining such operations, //the goal should be to arrive at some uniformity in the way things are done.// Ideally, when writing client code, one should be able to guess how to achieve some desired result.
       
       !guiding principle
      @@ -779,7 +782,7 @@ The approach taken to define any operation is based primarily on the ''~OO-way o
       !main tasks
       * you ''create a clip'' either from a source media or from another clip (copy, maybe clone?). The new clip always reflects the full size (and other properties) of the source used for creating.
       * you can request a clip to ''resize'', which always relates to its current dimensions.
      -* you can ''place or attach'' the clip to some point or other entity by creating a [[Placement]] from the clip.
      +* you can ''place or attach'' the clip to some point or other entity by creating a [[Placement]] from the clip. (&rarr; [[handling of Placements|PlacementHandling]])
       * you can ''adjust'' a placement relative to some other placement, meta object (i.e. selection), label or media, and this may cause the placement to resize or even delete the clip as necessary
       * you can perform ''adjustments'' on the whole EDL.
       All these operations propagate to directly dependant objects and may schedule global reconfigurations.
      @@ -1356,14 +1359,14 @@ From experiences with other middle scale projects, I prefer having the test code
       
       {{red{how to create a test stub for this interface...?}}}
      -
      -
      All sorts of "things" to be placed and manipulated by the user in the EDL. This interface abstracts the details and just provides
      -* a duration
      -* a [[Placement]]
      +
      +
      All sorts of "things" to be placed and manipulated by the user in the EDL. This interface abstracts the details and just supposes
      +* the media object has a duration
      +* it is allways //placed// in some manner, i.e. it is allways accessed via a [[Placement]]
       * {{red{and what else?}}}
       
      -
      +
      The ~MObjects Subsystem contains everything related to the [[EDL]] and the various Media Objects placed within. It is complemented by the Asset Management (see &rarr; [[Asset]]). Examples for [[MObjects|MObject]] being:
       * audio/video clips
       * effects and plugins
      @@ -1372,6 +1375,10 @@ From experiences with other middle scale projects, I prefer having the test code
       * labels and other (maybe functional) markup
       
       This Design strives to achieve a StrongSeparation between the low-level Structures used to carry out the actual rendering and the high level Entities living in the EDL and being manipulated by the user. In this high level view, the Objects are grouped and located by [[Placements|Placement]], providing a flexible and open way to express different groupings, locations and ordering constraints between the Media Objects.
      +&rarr; EditingOperations
      +&rarr; PlacementHandling
      +&rarr; SessionOverview
      +
       
       [img[Classess related to the EDL|uml/fig128133.png]]
       
      @@ -1443,11 +1450,11 @@ For the case in question this seems to be the ''resource allocation is construct And, last but not least, doing all actual allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides that, the ProcLayer code shouldn't issue "new" and "delete", rather it should use some central [[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.
      -
      +
      Based on practical experiences, Ichthyo tends to consider Multichannel Media as the base case, while counting media files providing just one single media stream as exotic corner cases. This may seem counter intuitive at first sight; you should think of  it as an attempt to avoid right from start some of the common shortcomings found in many video editors, especially
       * having to deal with keeping a "link" between audio and video clips
      -* silly limitations on the supported audio setups (e.g. mono, stereo and 5.1)
      -* unnecessary complexity when dealing with more realistic setups, esp. when dealing with dialogue scenes
      +* silly limitations on the supported audio setups (e.g. "sound is mono, stereo or Dolby-5.1")
      +* unnecessary complexity when dealing with more realistic setups, esp. when working on dialogue scenes
       * inability to edit stereoscopic (3D) video in a natural fashion
       
       !Compound Media
      @@ -1456,22 +1463,21 @@ Basically, each [[media asset|MediaAsset]] is considered to be a compound of sev
       So, when creating a clip out of such a compound media asset, the clip has to be a compound of elementary clips mirroring the given media asset's structure. Besides, it should be possible to //detach// and //attach// elementary clips from a compound clip. On the other hand, the [[Fixture]] created from the current state of the [[EDL]] is explicit to a great extent. So, in the Fixture we deal only with elementary clips placed to absolute positions, and thus the builder will see only simple non-compound clips and translate them into the corresponding source reading nodes.
       
       !Handling
      -* from a Media asset, we can get a [[Processing Pattern|ProcPatt]] describing how to build a render pipeline for this media
      +* from a Media asset, we can get a [[Processing Pattern (ProcPatt)|ProcPatt]] describing how to build a render pipeline for this media
       * we can create a Clip (MObject) from each Media, which will be linked back to the media asset internally.
       * moreover, creating a Clip will create and register a Clip asset as well, and this Clip asset will be tied to the original Clip and will show up in some special Category
       * media can be compound and the created Clips will mirror this compound structure
       * we distinguish elementay (non-compound) Clips from compound clips by concrete subtype. The builder can only handle elementary clips, because he needs to build a separate pipeline for every output channel. So the work of splitting common effect stacks for clips with several channels needs to be done when calculating the Fixture for the current EDL. The Builder expects to be able to build the render nodes corresponding to each entity found in the Fixture one by one.
       * the Builder gets at the ProcPatt (descriptor) of the underlying media for each clip and uses this description as a template to build the render pipeline. That is, the ProcPatt specifies the codec asset and maybe some additional effect assets (deinterlace, scale) necessary for feeding media data corresponding to this clip/media into the render nodes network.
      -
      -
      We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a representant of some general concept (Interface), or if we have a direct colaboration and thus need the Factory to provide
      -a more specific sub-Interface or even a concrete type.
      +
      +
      We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a instance of some general concept (Interface), or if we have a direct collaboration and thus need the Factory to provide a more specific sub-Interface or even a concrete type.
       
       !Object creation use cases
       !![[Assets|Asset]]
       |!Action|>|!creates |
       |loading a media file|asset::Media, asset::Codec| |
      -|viewing media|asset::Clip| for the whole Media, if not already existant|
      +|viewing media|asset::Clip| for the whole Media, if not already existent|
       |mark selection as clip|asset::Clip| doesn't add to EDL|
       |loading Plugin|asset::Effect| usually at program startup|
       |create Session|asset::Track, asset::OutPort| |
      @@ -1482,7 +1488,12 @@ a more specific sub-Interface or even a concrete type.
       |add Clip|session::Clip, FixedPlacement| |
       |attach Effect|session::Effect, RelativePlacement| |
       |start using Automation|session::Auto, asset::Dataset, RelativePlacement| |
      -
      + +!Invariants +when creating Objects, certain invariants have to be maintained. Because creating an Object can be considered an atomic operation and must not leave any related objects in an inconsistent state. Each of our interfaces implies some invariants: +* every Placement has a Subject it places +* MObjects are always created to be placed in some way or the other +* [[Assets|Asset]] manage a dependency graph. Creating a derived Object (e.g. a Clip from a Media) implies a new dependency. (&rarr; [[memory management|ManagementAssetRelation]] relies on this)
      Cinelerra2 introduced OpenGL support for rendering previews. I must admit, I am very unhappy with this, because
      @@ -2063,8 +2074,19 @@ DAMAGE.
       <html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
       ***/
      -
      +
      A Placement represents a //relation:// it is always linked to a //Subject// (this being a [[Media Object|MObject]]) and has the meaning to //place// this Subject in some manner, either relatively to other Media Objects, or by some Constraint or simply absolute at (time,track). The latter case is especially important and represented by a special [[Sub-Interface|ExplicitPlacement]]
      +
      +The fact of being placed in the [[Session|SessionOverview]]/[[EDL]]is constitutive for all sorts of [[MObject]]s, without Placement they make no sense. Thus &mdash; technically &mdash; Placements act as ''smart pointers''. Of course, there are several kinds of Placements and they are templated on the type of MObject they are refering to. Placements can be //aggregated// to increasingly constrain the resulting "location" of the refered ~MObject. See &rarr; [[handling of Placements|PlacementHandling]] for more details
      +
      +
      +
      [[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length).
      +
      +Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object. Each Placement has a ''kind'', which determines its actual placing and locating behaviour, but besides that, we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement of some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour.
      +
      +There is no limitation to one single Placement per ~MObject, indeed we can ''aggregate'' several Placements, resulting in their properties and constraints being combined to yield the actual position of the ~MObject refered by those Placements. 
      +
      +* {{red{to be worked out...}}} how to implement this, esp. the aggregation. Use a special "placement aggregation" subtype, or rather chain aggregated placements directly in the way a decorator works? And how to handle the case of a //over constrained// Placement?
       
      From fc1c39dc443eee666557a173da6a70c639b3a7a6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 12 Oct 2007 04:21:36 +0200 Subject: [PATCH 02/22] WIP: sketch handling placements and mobjects (as test) --- src/proc/mobject/placement.cpp | 3 +- src/proc/mobject/placement.hpp | 4 +- .../proc/mobject/placementbasictest.cpp | 100 ++++++++++++++++++ .../proc/mobject/session/addcliptest.cpp | 3 +- .../proc/mobject/session/deletecliptest.cpp | 3 +- .../mobject/session/rebuildfixturetest.cpp | 3 +- .../mobject/session/sessionmanagertest.cpp | 21 ++-- .../mobject/session/sessionstructuretest.cpp | 3 +- uml/cinelerra3/5.session | 9 +- wiki/renderengine.html | 4 +- 10 files changed, 132 insertions(+), 21 deletions(-) create mode 100644 tests/components/proc/mobject/placementbasictest.cpp diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp index a887eb771..27a7b1e4d 100644 --- a/src/proc/mobject/placement.cpp +++ b/src/proc/mobject/placement.cpp @@ -34,9 +34,8 @@ namespace mobject /** create an actual (explicit) placement while trying to * satisfy the network of adjacent objects and placements. - * TODO: need GC!!!!!!!!!!! */ - ExplicitPlacement& + ExplicitPlacement Placement::resolve () { } diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 1293b9745..df67d54f4 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -63,7 +63,7 @@ namespace mobject /** resolve the network of placement and * provide the resulting (explicit) placement. */ - ExplicitPlacement& resolve () ; + ExplicitPlacement resolve () ; protected: Placement (); @@ -77,7 +77,7 @@ namespace mobject /** - * Factory specialized for creating Media Asset objects. + * Factory specialized for creating Placement objects. */ class PlacementFactory : public cinelerra::Factory { diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp new file mode 100644 index 000000000..4fee8ba4c --- /dev/null +++ b/tests/components/proc/mobject/placementbasictest.cpp @@ -0,0 +1,100 @@ +/* + PlacementBasic(Test) - basic Placement and MObject handling + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "common/test/run.hpp" +#include "proc/mobject/session.hpp" +#include "proc/mobject/session/edl.hpp" +#include "proc/mobject/session/testclip.hpp" +#include "proc/mobject/placement.hpp" +#include "common/util.hpp" + +//#include +#include + +//using boost::format; +using cinelerra::Time; +using util::contains; +using std::string; +using std::cout; + + +namespace mobject + { + namespace session + { + namespace test + { + + + + + /******************************************************************* + * @test basic behaviour of Placements and access to MObjects. + * @see mobject::Placement + * @see mobject::MObject#create + * @see mobject::Placement#addPlacement + * @see mobject::Placement#resolve + */ + class PlacementBasic_test : public Test + { + typedef shared_ptr PM; + + virtual void + run (Arg arg) + { + // create Clip-MObject, which is wrapped into a placement (smart ptr) + PM media = asset::Media::create("test-1", VIDEO); + Placement pc = MObject::create(media); + + // can use the Clip-MObject interface by dereferencing the placement + PM clip_media = pc->getMedia(); + ASSERT (clip_media->ident.category.hasKind (VIDEO)); + + // using the Placement interface + // TODO: how to handle unterdetermined Placement? Throw? + FixedPlacement & fixpla = pc.addPlacement(Placement::FIXED, Time(1)); // TODO: the track?? + ExplicitPlacement expla = pc.resolve(); + ASSERT (expla.time == 1); + ASSERT (!expla.isOverdetermined()); + ASSERT (*expla == *pc); + ASSERT (*fixpla == *pc); + + // now overconstraining with another Placement + pc.addPlacement(Placement::FIXED, Time(2)); + expla = pc.resolve(); + ASSERT (expla.time == 2); // the latest addition wins + ASSERT (expla.isOverdetermined()); + } + }; + + + /** Register this test class... */ + LAUNCHER (PlacementBasic_test, "unit session"); + + + + } // namespace test + + } // namespace session + +} // namespace mobject diff --git a/tests/components/proc/mobject/session/addcliptest.cpp b/tests/components/proc/mobject/session/addcliptest.cpp index a88b36db9..65f0b96b1 100644 --- a/tests/components/proc/mobject/session/addcliptest.cpp +++ b/tests/components/proc/mobject/session/addcliptest.cpp @@ -55,7 +55,8 @@ namespace mobject */ class AddClip_test : public Test { - virtual void run(Arg arg) + virtual void + run (Arg arg) { PSess sess = Session::current; PMO clip = TestClip::create(); diff --git a/tests/components/proc/mobject/session/deletecliptest.cpp b/tests/components/proc/mobject/session/deletecliptest.cpp index 0275992b0..a44942a91 100644 --- a/tests/components/proc/mobject/session/deletecliptest.cpp +++ b/tests/components/proc/mobject/session/deletecliptest.cpp @@ -56,7 +56,8 @@ namespace mobject */ class DeleteClip_test : public Test { - virtual void run(Arg arg) + virtual void + run (Arg arg) { buildTestseesion1(); PSess sess = Session::current; diff --git a/tests/components/proc/mobject/session/rebuildfixturetest.cpp b/tests/components/proc/mobject/session/rebuildfixturetest.cpp index 62c77fe11..dc4943595 100644 --- a/tests/components/proc/mobject/session/rebuildfixturetest.cpp +++ b/tests/components/proc/mobject/session/rebuildfixturetest.cpp @@ -57,7 +57,8 @@ namespace mobject */ class RebuildFixture_test : public Test { - virtual void run(Arg arg) + virtual void + run (Arg arg) { PSess sess = Session::current; sess.clear(); diff --git a/tests/components/proc/mobject/session/sessionmanagertest.cpp b/tests/components/proc/mobject/session/sessionmanagertest.cpp index db42c9703..234f4ed93 100644 --- a/tests/components/proc/mobject/session/sessionmanagertest.cpp +++ b/tests/components/proc/mobject/session/sessionmanagertest.cpp @@ -50,7 +50,8 @@ namespace mobject */ class SessionManager_test : public Test { - virtual void run(Arg arg) + virtual void + run (Arg arg) { getCurrentSession (); clearSession(); @@ -66,7 +67,8 @@ namespace mobject /** @test accessing the current (global) session */ - void getCurrentSession () + void + getCurrentSession () { PSess sess = Session::current; ASSERT (sess->isValid()); @@ -77,7 +79,8 @@ namespace mobject * @todo implement all session content, implement * mobject and asset deletion operations. */ - void clearSession () + void + clearSession () { UNIMPLEMENTED ("clear objects in current session"); Session::current.clear(); @@ -87,7 +90,8 @@ namespace mobject * a pristine default session. * @todo define the "global session config", implement session default ctor */ - void resetSession () + void + resetSession () { UNIMPLEMENTED ("construct a pristine session"); Session::current.reset(); @@ -98,7 +102,8 @@ namespace mobject * objects are wired correctly. * @todo implement rebuilding session, implement mock session serializer */ - void loadMockSession () + void + loadMockSession () { UNIMPLEMENTED ("rebuild session using a mock serializer"); } @@ -108,7 +113,8 @@ namespace mobject * @param src string with serialized session data * @todo implement real session serializer */ - void loadSession (const string& src) + void + loadSession (const string& src) { UNIMPLEMENTED ("loding real sesion"); } @@ -117,7 +123,8 @@ namespace mobject * @param dest string recieving the generated serialized stream * @todo implement real session serializer */ - void saveSession (string& dest) + void + saveSession (string& dest) { UNIMPLEMENTED ("serialize current session"); } diff --git a/tests/components/proc/mobject/session/sessionstructuretest.cpp b/tests/components/proc/mobject/session/sessionstructuretest.cpp index d2bbe5477..f7dacdac8 100644 --- a/tests/components/proc/mobject/session/sessionstructuretest.cpp +++ b/tests/components/proc/mobject/session/sessionstructuretest.cpp @@ -55,7 +55,8 @@ namespace mobject */ class SessionStructure_test : public Test { - virtual void run(Arg arg) + virtual void + run (Arg arg) { PSess sess = Session::current; ASSERT (0 <= sess->currEDL().size()); // TODO implement diff --git a/uml/cinelerra3/5.session b/uml/cinelerra3/5.session index 517123540..7a80627f2 100644 --- a/uml/cinelerra3/5.session +++ b/uml/cinelerra3/5.session @@ -3,19 +3,20 @@ diagrams classdiagram_ref 130309 // Asset Kinds 860 633 100 4 0 0 active classdiagram_ref 128133 // Session structure - 860 633 100 4 47 0 + 860 633 100 4 89 0 classdiagram_ref 130437 // Media-Asset Relations 860 633 100 4 0 0 classdiagram_ref 128389 // Render Entities 688 506 100 4 120 0 end show_stereotypes -selected operation_ref 128005 // resolve +selected attribute_ref 128133 // relType open - -package_ref 128005 // design + deploymentview_ref 128773 // gen classview_ref 128901 // Assets + class_ref 128517 // MObject class_ref 128645 // Placement + class_ref 129413 // RelativePlacement classview_ref 129029 // Interface usecaseview_ref 128133 // usage end diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 44e8ba1d4..af38318d3 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -773,7 +773,7 @@ Cinelerra uses this term in a related manner but with a somewhat shifted focus ( In this usage, the EDL in most cases will be almost synonymous to the [[Session|SessionOverview]], just the latter emphasizes more the state aspect, as it can be thought as the current EDL contents contained in a file or data structure together with additional Option values and settings for the GUI. The Session is what you save and load, while the EDL rather denotes a structured collection of Objects placed in time.
      -
      +
      These are the tools provided to any client of the Proc layer for handling and manipulating the entities in the EDL. When defining such operations, //the goal should be to arrive at some uniformity in the way things are done.// Ideally, when writing client code, one should be able to guess how to achieve some desired result.
       
       !guiding principle
      @@ -794,7 +794,7 @@ While performing any manipulative task, the state of the object is considered in
       At the level of fine grained operations on individual entities, there is ''no support for parallelism''. Individual entities don't lock themselves. Tasks perform locking and are to be scheduled. Thus, we need an isolation layer towards all inherently multithreaded parts of the system, like the GUI or the renderengine.
       
       This has some obvious and some subtle consequences. Of course, manipulating //tasks// will be queued and scheduled somewhere. But as we rely on object identity and reference semantics for the entities in the EDL, some value changes are visible to  operations going on in parallel threads (e.g. rendering) and each operation on the EDL entities //has to be aware of this.//
      -Consequently, sometimes there needs to be done a ''self-replacement by copy'' followed by manipulation of the new copy, while ongoing processes use the unaltered original object until they receive some sort of reset.
      +Consequently, sometimes there needs to be done sort of a ''read-copy-update'', i.e. self-replacement by copy followed by manipulation of the new copy, while ongoing processes use the unaltered original object until they receive some sort of reset.
       
       !!undo
       Basically, each elementary operation has to record the informations necessary to be undone. It does so by registering a Memento with some central UndoManager facility. This Memento object contains a functor pre-bound with the needed parameter values. (Besides, the UndoManager is free to implement a second level of security by taking independent state snapshots). 
      
      From 08f10c2a2e5c8cc1051f9ebae3845ab176e27985 Mon Sep 17 00:00:00 2001
      From: Ichthyostega 
      Date: Sat, 13 Oct 2007 05:13:28 +0200
      Subject: [PATCH 03/22] WIP trying to get the Placement stuff right, but
       seemingly still having some design mismatch...
      
      ---
       doc/devel/uml/class128645.html                |  10 +--
       doc/devel/uml/class129285.html                |   4 +-
       doc/devel/uml/class129413.html                |   2 +-
       doc/devel/uml/class129541.html                |   2 +-
       doc/devel/uml/class129797.html                |   2 +-
       doc/devel/uml/class130053.html                |   2 +-
       doc/devel/uml/class130181.html                |   2 +-
       doc/devel/uml/class139909.html                |  23 ++++++
       doc/devel/uml/classes.html                    |   3 +-
       doc/devel/uml/classes_list.html               |   1 +
       doc/devel/uml/fig128133.png                   | Bin 62232 -> 63861 bytes
       doc/devel/uml/index.html                      |   7 +-
       doc/devel/uml/index_66.html                   |   2 +-
       doc/devel/uml/index_67.html                   |  28 ++++----
       doc/devel/uml/index_69.html                   |   4 +-
       doc/devel/uml/index_72.html                   |   2 +-
       doc/devel/uml/index_73.html                   |   2 +-
       doc/devel/uml/index_78.html                   |   1 +
       doc/devel/uml/index_79.html                   |   2 +-
       doc/devel/uml/index_80.html                   |   2 +-
       doc/devel/uml/index_84.html                   |   4 +-
       doc/devel/uml/index_86.html                   |  14 ++--
       doc/devel/uml/public_operations.html          |   1 +
       src/proc/mobject/placement.hpp                |  36 ++--------
       src/proc/mobject/session/chainplacement.cpp   |  38 ++++++++++
       src/proc/mobject/session/chainplacement.hpp   |  55 ++++++++++++++
       .../proc/mobject/placementbasictest.cpp       |   4 +-
       uml/cinelerra3/128133.diagram                 |  55 ++++++++------
       uml/cinelerra3/128261                         |  67 ++++++++++++++----
       uml/cinelerra3/129285                         |  10 +--
       uml/cinelerra3/130437                         |  41 ++++++++++-
       uml/cinelerra3/5.session                      |   6 +-
       uml/cinelerra3/cinelerra3.prj                 |   2 +-
       wiki/renderengine.html                        |  13 +++-
       34 files changed, 325 insertions(+), 122 deletions(-)
       create mode 100644 doc/devel/uml/class139909.html
       create mode 100644 src/proc/mobject/session/chainplacement.cpp
       create mode 100644 src/proc/mobject/session/chainplacement.hpp
      
      diff --git a/doc/devel/uml/class128645.html b/doc/devel/uml/class128645.html
      index 88a24bf13..0281acf2a 100644
      --- a/doc/devel/uml/class128645.html
      +++ b/doc/devel/uml/class128645.html
      @@ -16,11 +16,13 @@
       
       
       
      -

      Declaration :

      • C++ : class Placement
      • Java : public interface Placement

      Directly inherited by : Allocation ExplicitPlacement FixedPlacement RelativePlacement

      -

      Artifact : placement

      +

      Declaration :

      • C++ : class Placement
      • Java : public interface Placement

      Directly inherited by : Allocation ExplicitPlacement RelativePlacement

      +

      used to specify the position of a MObject in the EDL. This can be done in various ways (absolute, relative).
      Placement at the same time acts as (refcounting) smart pointer for accessing the MObject.

      Artifact : placement

      Operation resolve

      Declaration :

      • Uml : + resolve() : ExplicitPlacement [ProcessingLayer::MObject]&
      • C++ : public: ExplicitPlacement [ProcessingLayer::MObject]& resolve ()

      create an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements.

      -
      Relation subject (<unidirectional association>)

      Declaration :

      • Uml : # subject : MObject, multiplicity : 1
      • C++ : protected: MObject* subject

      Placement acts as smart pointer

      -

      All public operations : resolve

      +
      Relation subject (<unidirectional association>)

      Declaration :

      • Uml : # subject : MObject, multiplicity : 1
      • C++ : protected: MObject* subject

      Placement acts as smart pointer

      +
      Operation chain

      Declaration :

      • Uml : + chain(in style : ) :
      • C++ : public: chain (const & style)

      create and add another Placement for this media object, thus increasingly constraining the (possible) position of this object.

      +
      Relation chain (<unidirectional association>)

      Declaration :

      Chain of additional Placements further constraining the position of this MObject

      +

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class129285.html b/doc/devel/uml/class129285.html index 0091fcd2d..ab298c57b 100644 --- a/doc/devel/uml/class129285.html +++ b/doc/devel/uml/class129285.html @@ -16,8 +16,8 @@ -

      Declaration :

      Artifact : fixedplacement

      +

      Declaration :

      Artifact : fixedplacement

      -

      All public operations : resolve

      +

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class129413.html b/doc/devel/uml/class129413.html index eb05d79ba..8dd65f6f6 100644 --- a/doc/devel/uml/class129413.html +++ b/doc/devel/uml/class129413.html @@ -24,6 +24,6 @@
      Attribut offset

      Declaration :

      • Uml : # offset : Time
      • C++ : protected: Time offset

      Offset the actual position by this (time) value relative to the anchor point. TODO: Representation?

      Class RelType
      -

      All public operations : resolve

      +

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class129541.html b/doc/devel/uml/class129541.html index 43f614b48..98c845e4d 100644 --- a/doc/devel/uml/class129541.html +++ b/doc/devel/uml/class129541.html @@ -22,6 +22,6 @@
      Attribut repr

      Declaration :

      • Uml : # repr : string
      • C++ : protected: string repr

      human readable representation of the condition characterizing this allocaton, e.g. "t >= 10"

      Operation get_repr

      Declaration :

      • Uml : + get_repr() : string
      • C++ : public: inline const string getRepr () const
      -

      All public operations : get_repr , resolve

      +

      All public operations : chain , get_repr , resolve

      diff --git a/doc/devel/uml/class129797.html b/doc/devel/uml/class129797.html index a68f76325..ed207461b 100644 --- a/doc/devel/uml/class129797.html +++ b/doc/devel/uml/class129797.html @@ -24,6 +24,6 @@
      Attribut track

      Declaration :

      • Uml : # track : Track [ProcessingLayer::MObject] *
      • C++ : protected: Track [ProcessingLayer::MObject] * track
      Relation <unidirectional association>

      Declaration :

      -

      All public operations : resolve

      +

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class130053.html b/doc/devel/uml/class130053.html index f88d2a19b..a754c6888 100644 --- a/doc/devel/uml/class130053.html +++ b/doc/devel/uml/class130053.html @@ -18,6 +18,6 @@

      Declaration :

      -

      All public operations : get_repr , resolve

      +

      All public operations : chain , get_repr , resolve

      diff --git a/doc/devel/uml/class130181.html b/doc/devel/uml/class130181.html index c1578a450..3ddc9b19f 100644 --- a/doc/devel/uml/class130181.html +++ b/doc/devel/uml/class130181.html @@ -18,6 +18,6 @@

      Declaration :

      -

      All public operations : get_repr , resolve

      +

      All public operations : chain , get_repr , resolve

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

      + + + + +

      Declaration :

      • C++ : class ChainPlacement

      Artifact : chainplacement

      + +
      Relation next (<unidirectional association>)

      Declaration :

      next additional Placement, if any

      + + diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 39a63ddb4..836be1c5b 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -29,6 +29,7 @@ BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. Categorytree like classification of Assets +ChainPlacement Clipbookkeeping (asset) view of a media clip. Clip Codecdescription of some media data decoder or encoder facility @@ -89,7 +90,7 @@ ParameterDescriptor and access object for a plugin parameter. Parameters may be provided with values from the session, and this values may be automated. ParamProviderinterfaceA facility to get the actual value of a plugin/effect parameter PathManagerWhile building a render engine, this Strategy class decides on the actual render strategy in accordance to the current controller settings (system state) -Placementinterface +Placementinterfaceused to specify the position of a MObject in the EDL. This can be done in various ways (absolute, relative).
      Placement at the same time acts as (refcounting) smart pointer for accessing the MObject. PluginAdapterAdapter used to integrage an effects processor in the render pipeline Prefetch Previewalternative version of the media data, probably with lower resolution diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 44865f171..7dc49d02d 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -30,6 +30,7 @@ BuilderFacade
      BuildInstruct
      Category
      +ChainPlacement
      Clip
      Clip
      Codec
      diff --git a/doc/devel/uml/fig128133.png b/doc/devel/uml/fig128133.png index 7a51ef88d6c0ebbcf5bf2eb214a92a95e6a196cd..f2238751adae5de38648b3e678036837e9fb0b42 100644 GIT binary patch literal 63861 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

      9a@9G8c?^g05 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%0AAQJB#4nEawA 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 A<^TWy diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index dc0e8f165..e976b2222 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -112,7 +112,7 @@ Documentation
      Artifact Cinelerra3

      Depends on common

      Depends on gui

      Depends on proc

      Depends on backend

      the main executable to be built

      -

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

      +

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

      Artifact main

      Artifact source

      @@ -378,6 +378,10 @@ Documentation
      Artifact meta

      abstract base class of all MObjects representing meta data or processing instructions

      Artifact source associated with : Meta

      + +
      Artifact chainplacement
      +

      Chaining and additionally constraining Placements

      +

      Artifact source associated with : ChainPlacement

      Artifact fixedplacement

      Artifact source associated with : FixedPlacement

      @@ -642,6 +646,7 @@ Documentation
      Class Parameter
      +

      2.2.2 Package Builder

      diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 5ed3d76c4..70cc864a7 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -34,8 +34,8 @@ buildableartifactmarker interface denoting any MObject able to be treated by Tools buildEngineoperationMain Operation of the Builder: create a render engine for a given part of the timeline Buildercomponent -builderpackagesourcecode package

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

      The Builder creating the Render Engine,
      located within the MObject Subsystem Builder Entitiesclass diagram Builder Workingsclass view BuilderFacadeclassProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index dc1b39579..2f29cffbf 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -23,32 +23,36 @@ Categoryclasstree like classification of Assets categoryartifacttree like classification of Assets causeattributea copy of the first exception encountered in this exception chain +chainrelationChain of additional Placements further constraining the position of this MObject +chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. +chainplacementartifactChaining and additionally constraining Placements +ChainPlacementclass checked_inrelationchecked_in objects are subject of cache aging and must be not in use checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging Cinelerra3artifactthe main executable to be built cinelerra3package -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance class instanceclass instance -class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance +class instanceclass instance clearoperationclear current session contents
      without resetting overall session config.
      Afterwards, the session will contain only one
      empty EDL, while all Assets are retained.
      Clipclassbookkeeping (asset) view of a media clip. -clipartifacta Media Clip clipartifactbookkeeping (asset) view of a media clip. +clipartifacta Media Clip Clipclass clipsrelation Codecclassdescription of some media data decoder or encoder facility diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 0c7bddcba..20380e20a 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,14 +18,14 @@ - + - + diff --git a/doc/devel/uml/index_72.html b/doc/devel/uml/index_72.html index 58b669cd2..a26e1439f 100644 --- a/doc/devel/uml/index_72.html +++ b/doc/devel/uml/index_72.html @@ -24,8 +24,8 @@ - +
      NameKindDescription
      edlartifactthe (high level) Edit Decision List within the current Session
      EDLclass
      EDLcomponent
      EDLclass
      EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
      EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
      edlsrelation
      EffectclassEffect or media processing component
      effectartifactEffect or media processing component
      effectartifactEDL representation of a pluggable and automatable effect.
      effectartifactEffect or media processing component
      Effectclass
      elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
      enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
      howtoProcoperation@return descriptor how to build a render pipeline corresponding to this media
      Hubclass
      hubartifactspecial ProcNode used to build data distributing connections
      HUEclass instance
      HUEclass instance
      HUEclass instance
      diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 0f82f3fd9..496421c53 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,8 +20,8 @@ idattributeAsset primary key. In Memory Databaseclass diagram inFixtureactivity action pin -inputclass instance inputclass instance +inputclass instance inputclass instance instanceoperation instructionsrelation diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index d4d5daa81..7a0c5e875 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -18,6 +18,7 @@ + diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index 863a630ae..b34c12000 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,9 +19,9 @@ + - diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index 20ee4971b..2e0da44b5 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -26,7 +26,7 @@ - + diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 98fe8201c..1739030f8 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -40,13 +40,13 @@ - - + +
      NameKindDescription
      nameattributeelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique.
      nextrelationnext additional Placement, if any
      nodecreatertoolartifactcentral Tool implementing the Renderengine building
      NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render.
      nodesrelation
      NameKindDescription
      offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation?
      orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core cinelerra-3 codebase is "cin3".
      ouputclass instance
      ouputclass instance
      ouputclass instance
      ouputclass instance
      OutPortclassstructural asset corresponding to some port generating media output
      outportartifactstructural asset corresponding to some port generating media output
      outputrelation
      PathManagerclassWhile building a render engine, this Strategy class decides on the actual render strategy in accordance to the current controller settings (system state)
      pathmanagerartifactManager for deciding the actual render strategy
      placementartifactKey Abstraction: a way to place and locate a Media Object
      Placementclass
      Placementclassused to specify the position of a MObject in the EDL. This can be done in various ways (absolute, relative).
      Placement at the same time acts as (refcounting) smart pointer for accessing the MObject.
      playoperationTODO: will probably be handled differently (see Cehteh)
      playlistnode
      plugIDattributeIdentifier of the Plugin to be used
      tracksrelation
      Trafoclass
      trafoartifacttransforming processing Node
      treatoperation
      treatoperation
      treatoperation
      treatoperation
      treatoperation
      treatoperation
      treatoperation
      treatoperation
      treatoperation
      treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated.
      diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index 4eb1f6d88..0ae05e4c3 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -22,20 +22,20 @@ vframeartifacta buffer and render process holding a Video frame vid1class instance vid1class instance -vid_Aclass instance -vid_Aclass instance -vid_aclass instance -vid_aclass instance vid_Aclass instance +vid_Aclass instance +vid_aclass instance +vid_Aclass instance +vid_aclass instance videoclass instance -videoclass instance videoclass instance +videoclass instance videoclass instance video1class instance -video1class instance -video1class instance video1class instance +video1class instance video1class instance +video1class instance video1class instance VRenderclassRepresentation of a Video render process. (Encapsulates the video buffers for the actual calculations) vrenderartifactRepresentation of a Video render process diff --git a/doc/devel/uml/public_operations.html b/doc/devel/uml/public_operations.html index 3143920e2..745c339b7 100644 --- a/doc/devel/uml/public_operations.html +++ b/doc/devel/uml/public_operations.html @@ -21,6 +21,7 @@ buildAssembler buildEngineBuilderFacadeMain Operation of the Builder: create a render engine for a given part of the timeline buildProcessorPathManager +chainPlacementcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. clearSessManagerclear current session contents
      without resetting overall session config.
      Afterwards, the session will contain only one
      empty EDL, while all Assets are retained.
      configureToolFactory createClipMediacreate a (possibly compound) Clip refering to this media, ready to be added to the EDL. diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index df67d54f4..c1e7fc022 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -27,6 +27,7 @@ #include "common/time.hpp" #include "common/factory.hpp" #include "proc/mobject/mobject.hpp" +#include "proc/mobject/session/chainplacement.hpp" #include "proc/mobject/session/track.hpp" @@ -34,12 +35,11 @@ namespace mobject { - class Placement; class ExplicitPlacement; - class PlacementFactory; - class Placement + template /////TODO: unsolved design problem here! + class Placement : public shared_ptr { protected: typedef cinelerra::Time Time; @@ -47,18 +47,7 @@ namespace mobject public: - MObject* subject; - - /** - * styles of placement. - */ - enum Style - { - FIXED, - RELATIVE - }; - - static PlacementFactory create; + ChainPlacement chain; /** resolve the network of placement and * provide the resulting (explicit) placement. @@ -67,28 +56,11 @@ namespace mobject protected: Placement (); - friend class PlacementFactory; }; - typedef shared_ptr PPla; - - - /** - * Factory specialized for creating Placement objects. - */ - class PlacementFactory : public cinelerra::Factory - { - public: - typedef shared_ptr PType; - typedef cinelerra::Time Time; - - PType operator() (Placement::Style, Time, PMO subject); - - }; - } // namespace mobject diff --git a/src/proc/mobject/session/chainplacement.cpp b/src/proc/mobject/session/chainplacement.cpp new file mode 100644 index 000000000..3c5393ddd --- /dev/null +++ b/src/proc/mobject/session/chainplacement.cpp @@ -0,0 +1,38 @@ +/* + ChainPlacement - Chaining and additionally constraining Placements + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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/chainplacement.hpp" +#include "proc/mobject/placement.hpp" + +namespace mobject + { + namespace session + { + + /** */ + + + + } // namespace mobject::session + +} // namespace mobject diff --git a/src/proc/mobject/session/chainplacement.hpp b/src/proc/mobject/session/chainplacement.hpp new file mode 100644 index 000000000..db71b8c1f --- /dev/null +++ b/src/proc/mobject/session/chainplacement.hpp @@ -0,0 +1,55 @@ +/* + CHAINPLACEMENT.hpp - Chaining and additionally constraining Placements + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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_CHAINPLACEMENT_H +#define MOBJECT_SESSION_CHAINPLACEMENT_H + + + + +namespace mobject + { + class Placement; + + namespace session + { + class FixedPlacement; + class RelativePlacement; + + + template + struct ChainPlacement + { + protected: + /** next additional Placement, if any */ + Placement * next; + public: + + FixedPlacement& operator() (Time); + + }; + + } // namespace mobject::session + +} // namespace mobject +#endif diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp index 4fee8ba4c..75b87f269 100644 --- a/tests/components/proc/mobject/placementbasictest.cpp +++ b/tests/components/proc/mobject/placementbasictest.cpp @@ -72,7 +72,7 @@ namespace mobject // using the Placement interface // TODO: how to handle unterdetermined Placement? Throw? - FixedPlacement & fixpla = pc.addPlacement(Placement::FIXED, Time(1)); // TODO: the track?? + FixedPlacement & fixpla = pc.chain(Placement::FIXED, Time(1)); // TODO: the track?? ExplicitPlacement expla = pc.resolve(); ASSERT (expla.time == 1); ASSERT (!expla.isOverdetermined()); @@ -80,7 +80,7 @@ namespace mobject ASSERT (*fixpla == *pc); // now overconstraining with another Placement - pc.addPlacement(Placement::FIXED, Time(2)); + pc.chain(Placement::FIXED, Time(2)); expla = pc.resolve(); ASSERT (expla.time == 2); // the latest addition wins ASSERT (expla.isOverdetermined()); diff --git a/uml/cinelerra3/128133.diagram b/uml/cinelerra3/128133.diagram index a1d67d92a..a6da87c99 100644 --- a/uml/cinelerra3/128133.diagram +++ b/uml/cinelerra3/128133.diagram @@ -22,7 +22,7 @@ classcanvas 129413 class_ref 128517 // MObject end classcanvas 129669 class_ref 128645 // Placement draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 574 129 2000 + xyz 539 121 2000 end classcanvas 129925 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_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 @@ -46,15 +46,15 @@ classcanvas 131973 class_ref 129157 // Meta end classcanvas 132229 class_ref 129285 // FixedPlacement draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 665 373 2000 + xyz 678 374 2005 end classcanvas 132869 class_ref 129413 // RelativePlacement draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 479 276 2000 + xyz 477 342 2000 end classcanvas 134149 class_ref 129541 // Allocation draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 590 373 2000 + xyz 592 342 2000 end classcanvas 134405 class_ref 129669 // Label 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 @@ -62,7 +62,7 @@ classcanvas 134405 class_ref 129669 // Label end classcanvas 135429 class_ref 129797 // ExplicitPlacement draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 660 233 2004 + xyz 673 258 2004 end classcanvas 135813 class_ref 129797 // ExplicitPlacement 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 @@ -73,7 +73,7 @@ classcanvas 136581 class_ref 129925 // Auto xyz 375 466 2005 end note 136837 "Placement \"locates\" a Media Object" - xyzwh 368 83 3005 207 36 + xyzwh 370 73 3005 207 36 textcanvas 136965 "the Timeline is a list of placements reduced to absolute coordinates (time, track)" xyzwh 464 925 2000 121 90 textcanvas 137093 "Fixture is the actual assembly of various Media Objects ready to be performed" @@ -102,6 +102,10 @@ classcanvas 139653 class_ref 139781 // SessManager draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 101 301 2000 end +classcanvas 141317 class_ref 139909 // ChainPlacement + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 677 148 2000 + end relationcanvas 128389 relation_ref 128005 // from ref 128005 z 1999 to ref 128133 role_a_pos 201 603 3000 no_role_b @@ -152,34 +156,29 @@ relationcanvas 132101 relation_ref 129669 // from ref 131973 z 1999 to ref 130949 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 132485 relation_ref 129797 // - from ref 132229 z 1999 to ref 129669 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 132997 relation_ref 129925 // from ref 132869 z 1999 to point 529 240 line 133893 z 1999 to ref 129413 role_a_pos 413 204 3000 no_role_b - multiplicity_a_pos 401 197 3000 multiplicity_b_pos 515 251 3000 + multiplicity_a_pos 401 197 3000 multiplicity_b_pos 515 317 3000 relationcanvas 134533 relation_ref 130309 // from ref 134405 z 1999 to ref 131973 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 135173 relation_ref 130565 // - from ref 134149 z 1999 to point 610 312 - line 140037 z 1999 to ref 129669 + from ref 134149 z 1999 to point 576 266 + line 142853 z 1999 to ref 129669 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 135301 relation_ref 130693 // from ref 132869 z 1999 to ref 129669 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 135557 relation_ref 130821 // - from ref 132229 z 1999 to ref 135429 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 135685 relation_ref 130949 // - from ref 135429 z 1999 to ref 129669 + geometry VHV + from ref 135429 z 1999 to point 724 236 + line 141445 z 1999 to point 576 236 + line 141573 z 1999 to ref 129669 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 135941 relation_ref 131077 // @@ -209,7 +208,7 @@ relationcanvas 138757 relation_ref 137093 // geometry VHr from ref 138629 z 1999 stereotype "<>" xyz 479 716 3000 to point 517 714 line 138885 z 1999 to ref 135813 - role_a_pos 524 717 3000 no_role_b + role_a_pos 529 783 3000 no_role_b multiplicity_a_pos 505 783 3000 no_multiplicity_b relationcanvas 139141 relation_ref 140805 // from ref 139013 z 1999 to ref 131461 @@ -227,6 +226,20 @@ relationcanvas 139781 relation_ref 142853 // multiplicity_a_pos 126 426 3000 no_multiplicity_b relationcanvas 140165 relation_ref 142981 // from ref 129669 z 1999 to ref 129413 - role_a_pos 413 146 3000 no_role_b - multiplicity_a_pos 403 146 3000 multiplicity_b_pos 547 148 3000 + role_a_pos 401 145 3000 no_role_b + multiplicity_a_pos 401 178 3000 multiplicity_b_pos 512 178 3000 +relationcanvas 140293 relation_ref 143109 // + from ref 132229 z 1999 to ref 135429 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 142213 relation_ref 143237 // + from ref 129669 z 1999 to ref 141317 + role_a_pos 640 145 3000 no_role_b + multiplicity_a_pos 664 171 3000 no_multiplicity_b +relationcanvas 142341 relation_ref 143365 // + from ref 141317 z 1999 to point 724 207 + line 142597 z 1999 to point 637 207 + line 142725 z 1999 to ref 129669 + role_a_pos 640 191 3000 no_role_b + no_multiplicity_a no_multiplicity_b end diff --git a/uml/cinelerra3/128261 b/uml/cinelerra3/128261 index 60051e702..de4cec32a 100644 --- a/uml/cinelerra3/128261 +++ b/uml/cinelerra3/128261 @@ -1,6 +1,6 @@ format 40 "MObject" // ProcessingLayer::MObject - revision 23 + revision 24 modified_by 5 "hiv" // class settings //class diagram settings @@ -433,6 +433,8 @@ ${members}}; " explicit_switch_type "" + comment "used to specify the position of a MObject in the EDL. This can be done in various ways (absolute, relative). +Placement at the same time acts as (refcounting) smart pointer for accessing the MObject." operation 128005 "resolve" public explicit_return_type "ExplicitPlacement [ProcessingLayer::MObject]&" nparams 0 @@ -458,6 +460,33 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} classrelation_ref 144901 // subject () b multiplicity "1..*" parent class_ref 128517 // MObject end + + operation 134277 "chain" + public explicit_return_type "" + nparams 1 + param in name "style" explicit_type "" + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}const ${t0}& ${p0}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}const ${t0}& ${p0}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + comment "create and add another Placement for this media object, thus increasingly constraining the (possible) position of this object." + end + + classrelation 145413 // chain () + relation 143237 ---> + a role_name "chain" multiplicity "1" protected + comment "Chain of additional Placements further constraining the position of this MObject" + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 145413 // chain () + b multiplicity "" parent class_ref 139909 // ChainPlacement + end end class 129797 "ExplicitPlacement" @@ -683,19 +712,11 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 130437 // - relation 129797 ---|> + classrelation 145285 // + relation 143109 ---|> a public cpp default "${type}" - classrelation_ref 130437 // - b multiplicity "" parent class_ref 128645 // Placement - end - - classrelation 131461 // - relation 130821 -_-|> - a public - cpp default "${type}" - classrelation_ref 131461 // + classrelation_ref 145285 // b multiplicity "" parent class_ref 129797 // ExplicitPlacement end end @@ -1058,6 +1079,28 @@ ${inlines} comment "Provides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter" end + + class 139909 "ChainPlacement" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 145541 // next () + relation 143365 ---> + a role_name "next" multiplicity "" protected + comment "next additional Placement, if any" + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 145541 // next () + b multiplicity "" parent class_ref 128645 // Placement + end + end end package_ref 128901 // Builder diff --git a/uml/cinelerra3/129285 b/uml/cinelerra3/129285 index 724a630bd..1c121e419 100644 --- a/uml/cinelerra3/129285 +++ b/uml/cinelerra3/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 3 + revision 4 modified_by 5 "hiv" // class settings //class diagram settings @@ -26,7 +26,7 @@ format 40 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 - package_ref 128133 // AssetManager + package_ref 128133 // Asset package_ref 128261 // MObject @@ -222,8 +222,6 @@ format 40 "100" end relations - relation_ref 128645 // - classinstance_ref 130053 // end end @@ -248,8 +246,6 @@ format 40 "\"Hue\"" end relations - relation_ref 128645 // - classinstance_ref 130309 // end end @@ -276,8 +272,6 @@ format 40 "\"Hue\"" end relations - relation_ref 128645 // - classinstance_ref 130309 // end end diff --git a/uml/cinelerra3/130437 b/uml/cinelerra3/130437 index 514cc634e..df17fa821 100644 --- a/uml/cinelerra3/130437 +++ b/uml/cinelerra3/130437 @@ -1,6 +1,6 @@ format 40 "session" // design::codegen::proc::mobject::session - revision 9 + revision 10 modified_by 5 "hiv" // class settings //class diagram settings @@ -511,6 +511,45 @@ ${namespace_end}" comment "abstract base class of all MObjects representing meta data or processing instructions" end + artifact 139013 "chainplacement" + stereotype "source" + cpp_h "/* + ${NAME}.hpp - ${description} +@{CopyrightClaim}@{GPLHeader} +*/ + + +#ifndef ${NAMESPACE}_${NAME}_H +#define ${NAMESPACE}_${NAME}_H + +${includes} +${declarations} + + +${namespace_start} + +${definition} +${namespace_end} +#endif +" + cpp_src "/* + ${Name} - ${description} +@{CopyrightClaim}@{GPLHeader} +* *****************************************************/ + + +${includes} +${namespace_start} + + +${members} +${namespace_end}" + associated_classes + class_ref 139909 // ChainPlacement + end + comment "Chaining and additionally constraining Placements" + end + artifact 129797 "fixedplacement" stereotype "source" cpp_h "/* diff --git a/uml/cinelerra3/5.session b/uml/cinelerra3/5.session index 7a80627f2..49af64898 100644 --- a/uml/cinelerra3/5.session +++ b/uml/cinelerra3/5.session @@ -3,16 +3,18 @@ diagrams classdiagram_ref 130309 // Asset Kinds 860 633 100 4 0 0 active classdiagram_ref 128133 // Session structure - 860 633 100 4 89 0 + 860 633 100 4 0 0 classdiagram_ref 130437 // Media-Asset Relations 860 633 100 4 0 0 classdiagram_ref 128389 // Render Entities 688 506 100 4 120 0 end show_stereotypes -selected attribute_ref 128133 // relType +selected class_ref 129285 // FixedPlacement open + deploymentview_ref 128133 // EXE Deployment deploymentview_ref 128773 // gen + deploymentview_ref 128901 // gen classview_ref 128901 // Assets class_ref 128517 // MObject class_ref 128645 // Placement diff --git a/uml/cinelerra3/cinelerra3.prj b/uml/cinelerra3/cinelerra3.prj index 4680e3711..efde6fe95 100644 --- a/uml/cinelerra3/cinelerra3.prj +++ b/uml/cinelerra3/cinelerra3.prj @@ -1,6 +1,6 @@ format 40 "cinelerra3" - revision 32 + revision 33 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index af38318d3..eefa14ca2 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -2079,14 +2079,23 @@ DAMAGE. The fact of being placed in the [[Session|SessionOverview]]/[[EDL]]is constitutive for all sorts of [[MObject]]s, without Placement they make no sense. Thus &mdash; technically &mdash; Placements act as ''smart pointers''. Of course, there are several kinds of Placements and they are templated on the type of MObject they are refering to. Placements can be //aggregated// to increasingly constrain the resulting "location" of the refered ~MObject. See &rarr; [[handling of Placements|PlacementHandling]] for more details
      -
      +
      [[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length).
       
       Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object. Each Placement has a ''kind'', which determines its actual placing and locating behaviour, but besides that, we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement of some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour.
       
       There is no limitation to one single Placement per ~MObject, indeed we can ''aggregate'' several Placements, resulting in their properties and constraints being combined to yield the actual position of the ~MObject refered by those Placements. 
       
      -* {{red{to be worked out...}}} how to implement this, esp. the aggregation. Use a special "placement aggregation" subtype, or rather chain aggregated placements directly in the way a decorator works? And how to handle the case of a //over constrained// Placement?
      +!design decisions
      +* Placements can be aggregated in a sort of chain.
      +* resolving into an ExplicitPlacement traverses this chain
      +* //overconstraining// a placement is not an error, we just stop traversing the chain (ignoring the remaining additionla Placements) at the moment the position is completely defined. 
      +* {{red{question...}}} how to implement this? externally, decorator-style or using the State pattern?
      +* {{red{problem...}}} how to get at the individual MObject sub-Interfaces. Why is this a Problem?
      +*# we want the EDL/Fixture to be a collection of Placements. This means, either we store pointers, or Placement needs to be //one// unique type!
      +*# but if Placement is //a single type//, then we can get only MObjects from a Placement.
      +*# then either we had to do everything by a visitor (which gets the concrete subtype dynamically), or we'd end up switching on type.
      +
       
      From a089e5ff15cffa1be6e7d521b8e2a1c5d0c995e2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 18 Oct 2007 17:29:01 +0200 Subject: [PATCH 04/22] WIP maybe nailed down the design problem regarding placements now.... --- doc/devel/uml/class128645.html | 4 +- doc/devel/uml/class129285.html | 7 +- doc/devel/uml/class129413.html | 7 +- doc/devel/uml/class129541.html | 4 +- doc/devel/uml/class129797.html | 3 +- doc/devel/uml/class130053.html | 2 +- doc/devel/uml/class130181.html | 2 +- doc/devel/uml/class133893.html | 2 +- doc/devel/uml/class139909.html | 11 ++- doc/devel/uml/classes.html | 6 +- doc/devel/uml/classes_list.html | 6 +- doc/devel/uml/fig128133.png | Bin 63861 -> 64119 bytes doc/devel/uml/index.html | 27 +++--- doc/devel/uml/index_65.html | 4 +- doc/devel/uml/index_66.html | 2 +- doc/devel/uml/index_67.html | 12 +-- doc/devel/uml/index_70.html | 4 +- doc/devel/uml/index_72.html | 2 +- doc/devel/uml/index_73.html | 4 +- doc/devel/uml/index_76.html | 2 + doc/devel/uml/index_77.html | 2 +- doc/devel/uml/index_78.html | 2 +- doc/devel/uml/index_79.html | 2 +- doc/devel/uml/index_82.html | 6 +- doc/devel/uml/index_83.html | 4 +- doc/devel/uml/index_84.html | 4 +- doc/devel/uml/index_86.html | 18 ++-- src/proc/mobject/placement.hpp | 56 ++++++++++- src/proc/mobject/session/allocation.cpp | 2 +- src/proc/mobject/session/allocation.hpp | 9 +- src/proc/mobject/session/clip.hpp | 3 + .../{fixedplacement.cpp => fixedlocation.cpp} | 4 +- .../{fixedplacement.hpp => fixedlocation.hpp} | 17 ++-- .../{chainplacement.cpp => locatingpin.cpp} | 4 +- .../{chainplacement.hpp => locatingpin.hpp} | 13 ++- ...tiveplacement.cpp => relativelocation.cpp} | 0 ...tiveplacement.hpp => relativelocation.hpp} | 10 +- uml/cinelerra3/128133.diagram | 87 ++++++++++-------- uml/cinelerra3/128261 | 61 ++++++------ uml/cinelerra3/129285 | 6 +- uml/cinelerra3/130437 | 17 ++-- uml/cinelerra3/5.session | 14 +-- uml/cinelerra3/cinelerra3.prj | 2 +- wiki/renderengine.html | 23 +++-- 44 files changed, 270 insertions(+), 207 deletions(-) rename src/proc/mobject/session/{fixedplacement.cpp => fixedlocation.cpp} (88%) rename src/proc/mobject/session/{fixedplacement.hpp => fixedlocation.hpp} (70%) rename src/proc/mobject/session/{chainplacement.cpp => locatingpin.cpp} (89%) rename src/proc/mobject/session/{chainplacement.hpp => locatingpin.hpp} (79%) rename src/proc/mobject/session/{relativeplacement.cpp => relativelocation.cpp} (100%) rename src/proc/mobject/session/{relativeplacement.hpp => relativelocation.hpp} (84%) diff --git a/doc/devel/uml/class128645.html b/doc/devel/uml/class128645.html index 0281acf2a..7b271a2ee 100644 --- a/doc/devel/uml/class128645.html +++ b/doc/devel/uml/class128645.html @@ -16,13 +16,13 @@ -

      Declaration :

      • C++ : class Placement
      • Java : public interface Placement

      Directly inherited by : Allocation ExplicitPlacement RelativePlacement

      +

      Declaration :

      • C++ : class Placement
      • Java : public interface Placement

      Directly inherited by : ExplicitPlacement

      used to specify the position of a MObject in the EDL. This can be done in various ways (absolute, relative).
      Placement at the same time acts as (refcounting) smart pointer for accessing the MObject.

      Artifact : placement

      Operation resolve

      Declaration :

      • Uml : + resolve() : ExplicitPlacement [ProcessingLayer::MObject]&
      • C++ : public: ExplicitPlacement [ProcessingLayer::MObject]& resolve ()

      create an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements.

      Relation subject (<unidirectional association>)

      Declaration :

      • Uml : # subject : MObject, multiplicity : 1
      • C++ : protected: MObject* subject

      Placement acts as smart pointer

      Operation chain

      Declaration :

      • Uml : + chain(in style : ) :
      • C++ : public: chain (const & style)

      create and add another Placement for this media object, thus increasingly constraining the (possible) position of this object.

      -
      Relation chain (<unidirectional association>)

      Declaration :

      Chain of additional Placements further constraining the position of this MObject

      +
      Relation chain (<unidirectional association>)

      Declaration :

      Chain of additional Placements further constraining the position of this MObject

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class129285.html b/doc/devel/uml/class129285.html index ab298c57b..8393d4269 100644 --- a/doc/devel/uml/class129285.html +++ b/doc/devel/uml/class129285.html @@ -4,20 +4,19 @@ -Class FixedPlacement +Class FixedLocation -
      Class FixedPlacement
      +
      Class FixedLocation

      -

      Declaration :

      Artifact : fixedplacement

      +

      Declaration :

      Artifact : fixedlocation

      -

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class129413.html b/doc/devel/uml/class129413.html index 8dd65f6f6..b8fa2c81b 100644 --- a/doc/devel/uml/class129413.html +++ b/doc/devel/uml/class129413.html @@ -4,19 +4,19 @@ -Class RelativePlacement +Class RelativeLocation -
      Class RelativePlacement
      +
      Class RelativeLocation

      -

      Declaration :

      • C++ : class RelativePlacement : public Placement

      Artifact : relativeplacement

      +

      Declaration :

      Artifact : relativelocation

      Relation anchor (<unidirectional association>)

      Declaration :

      • Uml : # anchor : MObject, multiplicity : 1
      • C++ : protected: MObject* anchor
      Attribut relType
      @@ -24,6 +24,5 @@
      Attribut offset

      Declaration :

      • Uml : # offset : Time
      • C++ : protected: Time offset

      Offset the actual position by this (time) value relative to the anchor point. TODO: Representation?

      Class RelType
      -

      All public operations : chain , resolve

      diff --git a/doc/devel/uml/class129541.html b/doc/devel/uml/class129541.html index 98c845e4d..40d20683a 100644 --- a/doc/devel/uml/class129541.html +++ b/doc/devel/uml/class129541.html @@ -16,12 +16,12 @@ -

      Declaration :

      Directly inherited by : Constraint Wish

      +

      Declaration :

      Directly inherited by : Constraint Wish

      a directive to place a MObject in a specific way

      Artifact : allocation

      Attribut repr

      Declaration :

      • Uml : # repr : string
      • C++ : protected: string repr

      human readable representation of the condition characterizing this allocaton, e.g. "t >= 10"

      Operation get_repr

      Declaration :

      • Uml : + get_repr() : string
      • C++ : public: inline const string getRepr () const
      -

      All public operations : chain , get_repr , resolve

      +

      All public operations : get_repr

      diff --git a/doc/devel/uml/class129797.html b/doc/devel/uml/class129797.html index ed207461b..934410392 100644 --- a/doc/devel/uml/class129797.html +++ b/doc/devel/uml/class129797.html @@ -16,8 +16,7 @@ -

      Declaration :

      • C++ : class ExplicitPlacement : public Placement
      • Java : public interface ExplicitPlacement

      Directly inherited by : FixedPlacement

      -

      Artifact : explicitplacement

      +

      Declaration :

      • C++ : class ExplicitPlacement : public Placement
      • Java : public interface ExplicitPlacement

      Artifact : explicitplacement

      Attribut time

      Declaration :

      • Uml : # time : Time
      • C++ : protected: Time time
      diff --git a/doc/devel/uml/class130053.html b/doc/devel/uml/class130053.html index a754c6888..7df85e17a 100644 --- a/doc/devel/uml/class130053.html +++ b/doc/devel/uml/class130053.html @@ -18,6 +18,6 @@

      Declaration :

      -

      All public operations : chain , get_repr , resolve

      +

      All public operations : get_repr

      diff --git a/doc/devel/uml/class130181.html b/doc/devel/uml/class130181.html index 3ddc9b19f..1d050e694 100644 --- a/doc/devel/uml/class130181.html +++ b/doc/devel/uml/class130181.html @@ -18,6 +18,6 @@

      Declaration :

      -

      All public operations : chain , get_repr , resolve

      +

      All public operations : get_repr

      diff --git a/doc/devel/uml/class133893.html b/doc/devel/uml/class133893.html index ed2c18147..ba0cbda57 100644 --- a/doc/devel/uml/class133893.html +++ b/doc/devel/uml/class133893.html @@ -16,7 +16,7 @@ -

      Declaration :

      • C++ : enum RelType
      • Java : public enum RelType

      the possible kinds of RelativePlacements

      nested in RelativePlacement

      +

      Declaration :

      • C++ : enum RelType
      • Java : public enum RelType

      the possible kinds of RelativePlacements

      nested in RelativeLocation

      Items :

      • SAMETIME
      • diff --git a/doc/devel/uml/class139909.html b/doc/devel/uml/class139909.html index c1cacb0df..210261f35 100644 --- a/doc/devel/uml/class139909.html +++ b/doc/devel/uml/class139909.html @@ -4,20 +4,21 @@ -Class ChainPlacement +Class LocatingPin -
        Class ChainPlacement
        +
        Class LocatingPin

        -

        Declaration :

        • C++ : class ChainPlacement

        Artifact : chainplacement

        - -
        Relation next (<unidirectional association>)

        Declaration :

        next additional Placement, if any

        +

        Declaration :

        • C++ : class LocatingPin

        Directly inherited by : Allocation FixedLocation RelativeLocation

        +

        An element with value semantics, which actually implements the placement of some MObject by positioning it in some way.

        Artifact : locatingpin

        + +
        Relation next (<unidirectional association>)

        Declaration :

        next additional LocatingPin, if any

        diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 836be1c5b..a93cd61e0 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -29,7 +29,6 @@ BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. Categorytree like classification of Assets -ChainPlacement Clipbookkeeping (asset) view of a media clip. Clip Codecdescription of some media data decoder or encoder facility @@ -60,7 +59,7 @@ FileMapCache FileProviderThis is the Factory for Files, whenever something wants to use some file (or temporary storage), This Factory will hand out some smart/shared pointer to a File object which will be used to retrieve Frames. FileReference -FixedPlacement +FixedLocation Fixture FrameFrames are just a low level lump of continous memory, most parts are opaque. Frames are memory sensitive, they will be small constant sized structures which can be efficently managed in a pool. FrameinterfaceTODO: 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 @@ -74,6 +73,7 @@ Invalid Label Link +LocatingPinAn element with value semantics, which actually implements the placement of some MObject by positioning it in some way. Lock Lock Logic @@ -99,7 +99,7 @@ ProcNodeinterfaceKey abstraction of the Render Engine: A Data processing Node ProcPattspecial type of structural Asset representing information how to build some part of the render engine's processing nodes network. ProjectorSpecial video processing node used to scale and translate image data. -RelativePlacement +RelativeLocation RelTypeenumthe possible kinds of RelativePlacements RenderEngine RenderStateEncapsulates the logic used to get a "current render process" in accordance to the currentyl applicable controller settings. The provided StateProxy serves to hold any mutalbe state used in the render process, so the rest of the render engine can be stateless. diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 7dc49d02d..d5c17b7d5 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -30,7 +30,6 @@ BuilderFacade
        BuildInstruct
        Category
        -ChainPlacement
        Clip
        Clip
        Codec
        @@ -61,7 +60,7 @@ FileMapCache
        FileProvider
        FileReference
        -FixedPlacement
        +FixedLocation
        Fixture
        Frame
        Frame
        @@ -75,6 +74,7 @@ Invalid
        Label
        Link
        +LocatingPin
        Lock
        Lock
        Logic
        @@ -100,7 +100,7 @@ ProcNode
        ProcPatt
        Projector
        -RelativePlacement
        +RelativeLocation
        RelType
        RenderEngine
        RenderState
        diff --git a/doc/devel/uml/fig128133.png b/doc/devel/uml/fig128133.png index f2238751adae5de38648b3e678036837e9fb0b42..ccbcf7d90466ac251af2c09560d08825f2e9fd7a 100644 GIT binary patch literal 64119 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%0DhbPc<*5 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,xP|x zXF=Q;bZB7NO3%Ra3A*3Tj-PdIX2Ej-qH3}G5~OcE@DbUQZullg3RVc{M<2xU!>#bY zXE?&IqT*2Gap$Ggrb(%8x7?aYX7X1WaiYGt+g_azWxk{>t8v|V*=w2hf~UXek?(ME zdgnxSK!_;Nu5ENF zN|%6iEu|4qK{K#Cr>)#pZ{EVb5p|o}RsNnEh$pm{ED2{GVrk;=dL#GOKNg z=R!9##muO$7h5j!&!ZV{;}2pEqp^`&C~@0U1t@p6dmj19gu@=&lJs!KN}j&6guaUP z%M82U9iOTpTt5h9kuFiQ(VImUoqQ6X++M8b! z_{fMhJlTtBCByVKI4UcL2`|o5i}CO`^5V~PDx42Z$;0>mX(zyqo(FKod4?5rAwlsqF#j1q^wt;Pry*AuP-dF z^2ZOw@30ybV&@Pr2WmEp$7I&+PS0*azX2#KkUdjjRw<_!dh6vCbo9Bue<6T7rL>fv zfq{XZ-o0}^9a;lJ!vrAvK+6g30zM872!5!LU%!5R@XyokrCu%!gP6>R4_J)06r-Bl&+ZRGXpD8NdHfRcVcXtQ`>>h zL2P8#(}Q=eK=g(NnVXxNz>NlvJwwC!+1Xi$4F<*3&!0aH4GbQK|M)@% zlnSFRdWjDn9`~O{31W0qRGLakND^#ln9|#-SUn78LwIWL z+CqiV^|(}&nk6VZ+uX=#AyYY>GV8X($`DYyA*vLh&C>3HABWI-+%tXaLp-ibOhc3X zp~Kw==<%W2Nf50C?GuR3%y)W5UHvWNAGTzROY)bugwMjW<0lP)kf%_<$P)B@vX5J%J3|KJ#Fwby@MFt+#qU=8sn0+g;@xPjQ0ePXZ4>lc%n9fE(rle*l^Z^QGn?@t&?E}4QVpN zMXwPyjruLGkHaf|+~24p@VYApR|?XP;Mm+W(gwq0coTla!O!GFET6q9);^y=`pUbwzVsF$6hHQ<-HcnNn? z@KJ`ZQVfbU%YU8&|Gv+$8|vdDYOcS{T7$QN^QWGGCpzuf_*K+jmb$(4`Lp4KohWT2 zsNAm|?4A53Ywa?`8}Ft1)zLnKzf*LBl?J}XJY6!Mz6gS#7G*m-UY=_d6qzIO2!!to zY6Za+B^XL0>`{5H@Inx0j906O>i#k~4EWXIt?@SalYKcmyE8YZY-cY8PUX#mj!u9_ zha3}<6uutLXJF(aLGWIO7$GC?uC7vWD3*^Ce78Q4>gt*TlhpOa!+?n)(+$SduYhu8VlVp~%HTIyl4;6Ws`_ z+CwCISY78Wo3gQvmMYLyZrAx)BB4a$oSU7WzxDn5dni;^+oG1MPqtn_HRE>r%zj#e zR?}(d_Iy?r9}FAW*m_2b?{f1cJO!WZHU*`MwQ+FQ;YbCD9~(#ZD#ZBuo|BM<_t=5Q z>a<>fRz>OO?DMssuGOci4flF3_I2m8aY-E&6%w8R*n-?otO9h)rn0ILTK`wI+;Veh z1d)WD9gD<=oVDsbmD_IIo?C!wtSnS~Rx-_d^kA7s{t~#0@1?fjIICRZU)`Uivlx4` zAa<@^h#BIYtfcMj?LoV%prD|r82tIOl5O=VD9U5MN% zw?~$j3qnyUBj5gRKJFewTTVycEog6_1asUsb8SWNZaqBKP!-jnZolIiiREPcz1MPX zR51#vshyPOP7SyOd5k8*pMU_6 z67VM)8Xh(u`r$#i1v@%{*hyDILql^jD>JiHq4%Wgar>`dNIt%Z&Uqnz{vp7bMn|E> zED)%CiUFZrWe}G&^()EcNY2q=tzlj&6LL=xJ=Tl+h0#+3^jCPje&)^qYzYTfUS3|a z$fRE}u7uJzg#~ukXV5TOSXe+<_r~rn2RnN~Nl9*YHjJTLV85R4Oh|~2uhRSN2a-wd zU4RD~KtG}172)X~3x|3)H_i;IhX+LN!}j#~5oMI|@$;;B_PsQCZX zJ+J9mA=@J9XlO(%#!72zB_uHAd!dUw-dptwhKZcJJEAx(CT0}Q+(53buBz$)>dGW0 zc5^$2Ef`eNtWMAx6q4p}^gJkC;?yGNL|tvz|61A zTV7WG0_g{3*co^UxMTI`8$3*!hb~{6f}e@Fsoi~oDQ5_$W~b*%o_h2{2Z2VR@Dl!r zjk);Rjhbdw#=qY$e}i=ZgFE&HvcaPzj|zD?R^^?mk7wO{ak1#$Uc%a#QwZUo8De=% zYugwA)iW)|-~F`PEH2m{{xMCjoRIuxd0;ax_GH*ZX6?4^|cunHqlxn*zvo{FzH zuRm;9lj+0E&8vv7wWm)n^#w{)6~qjDXkf11oEZm8mG$X6Z#G^u78X8BCeW^qKj?i@ zZ7~@io^bB0tu3NSOS+d=<;tGAzjH42)Y|biA{d)OVROR+r#(GH^PNdu<+QSL3M|37 zT8DSy`9(TbqmYpr65X)}>s*26c#vvPheYC&($}2oq64-$8O_B3(3XM!$ zWOwZ}VS9e?_&A7)`)klQ)7zTR6L-e_RMKi&?^}!m9)Bo$pg$ot_%Cv}V*2$xA$XUC za3_Zfr|X74sSD6&Fp>2&;$p1E*Pwvy8Sl1!YgbtP&D07SNIDnZn&C3d2le52RC6CX zT2+49&L5MmCVfgw^CE9-Q1yC<*!9)5=fD(;?vE0z79@F?X`&0l5)vL7C>&1k3$HvA ziP|D|8A(Y_rX0WZ#n#Vrq)G_k?rmL4>g7U**ifZB?NS^;C9#WXfe=(YAY-rCxb!w2 z!k50T=$6(f7Gi?bA_g6?CGKNt{lU6R&f40S#gBQ9OYD5V#N0ReP32pc0V0tr-gV}^ zuvha#X2m$l)#`Z9+bbAKg28lHAMcd`w3Sw2e>kfTlJj9-zg zyF<+E3Nfb%W~RLI7+156Ctd$!Yd&PtWDE|9y%bm}nbRkAdU8TC$%9ZtYqFAgPmaMc zeRk>#r4Ae0TbtF9xG(IURp+i?&`j2mKv!+^Hy()E$AD2OBE=ms}AdY z!^=CneF%^&0K|KHdqR$D3|=qnAl8(N<=TcJ4 z{BOp;O3UudRLzdq7GH&;yJXNG?Pzai}uWNjL%^vZ^wnhu3c2^jt7H zPjKTLE8G5R@)IxM&-NimW&urw-VZSIr?L-H)6ziE5)&N_`>{gg?fWZAA|fKN@k#pP z!$!&m0U0K6v@sRb)h=nViqm9le{(-hWec7Sl~$@?603A|We3IQNZX_OCf5-hY;0&i zT~BuhVUP>)F)=@#w&y?$ z52he4Tg}V>@`f-zsGOuk&|?q!Dqqstz;aIkVgfgXf^lqI9Lx?9gq?`!=+@WP;y-^z zs@JN5w`F(YeNRjzIy(AFk_{&(XJBC9^z<}r+3BNlJV#wNAzmi*b(yh( z)mO-UmFY8QtWr}k#E#AW(zyv+Oiu8!8h`eebxZ@2K#i9dov?_n`3Ud+FHb2Q9VITE z3NTkLGI@qAZwS7g>1jIT{9Q;PA&=xY)6+T__y%v@;vcX5^=LsN-b0K zlOyFfw^vV^cG=z4oZf*{p6jSJ zSWqJAN7hmyV4cxvaAcdqmzPV3vg_n{c?~!OlGa^>et$B{aiYzjp0BSb z-ky^OB0DH$n|F4|GwmJLMXyr|zUqwUN&YL5q$q_Um4t9#Le^!H>rp>W&9bEot5*C1 zBclCX?J5hJ$)0>knHKI$dzi$|uhJB~-St@P71P7f)+!egRH(L{cYd`?f=Ij%9buw& zhxDaD^A!j-FFp2*r3*MZL%`?rz@ZJg2ydAcIMnpy7GqmlK4${Rx&M4eDYG!*vpxR zf5murjWOKAeOxk4Fra^co?YqREiG<(;6I&sKKu>qMHe4@337^|b9WA&?jyT+sYGOH z@du5%)JITZ@g<4>`z3_x`8gPlY^0>5zWrdPL_A?a7_qH@rP4ngIev`?s_Ujl7h2>; zb5^;I)5+|v^2QW$%^UvRqX+UptqzZQ-ejc(TL65A3+Ela*6#bvkYC^j2>9;C#oL15 zBlr!f*H^gct=+>VeP-A$er5iD`fh5U3rHZ_8@JK?qU#^Q`p>7~C%6DCG%zU?h%Yb) zBdY(rTrc4TT+qeVWEG8uD&WMOQ8CL1gcTHOkA9(=dG~N}pI+X7o)qz)C*>u)I7Ga( z+_A4EKEYcAD$Bp%0^Ibxi({MkD|nih0%D3`fGzQ#Pl5LjcoE=*n|^o!UO-8Rf(#J* z^mWEpFFw2xlp^LHr~{KI{U2aM!5=mk@t9|7YTyO{a~5C~$V>;6bQ$_5B}m*tNAPzN~`6&WdM53jb03dltc zm~w>O8-Cp`3a_Qb7Dhuny?Zop``*3RK^eXM{n@#>hI8E9+#woJ^|AU9#U&b-Cp|JT zG1=MO9TvS!JTWoBrCYVLu|Y2U#tP>Q$G+q4>*;dI<;klyXl9Vo{fF1)8p{J`W zIBgLi&gajc-?jyZn8zGs^7<aHGS4Kla0~#p!zrPp`LdzYnQN$Dn zF4etTu%!{&>@0LACMG^=oy@u>4a*u>YA`V|ot>S5F#!zHp4JE=jIQ85G`ed}>)$hH zj}e^IUDDu*LGaGS1=wF8wulM|>8W&fe4PUmR#}b+!NLK>n|fcMKRSlO;kQ4T)We6@ zBye$Y!?|?V{{HRnd2$)SJY_03YHS|XJ#rl*7|#+9kyBHpg1W%q?&@{mwU~f!YhWdF zM_phS(PW4b+4xDzg8+=g_~2=GLbwKvzCD^e=Kp<3+#Ff=YZ5Ng!q89qqL-=N1tsA^ z?s9mlPYpjrOZs@8qb}!c#=Si$cQh1Yw!sB=iiW?-@y(h`R+mv%_DR4;3rvV~PfTCJ zcOQA_>OUh%o#>r$u2@33N0{&!d^4xTvFrKWNgwt`0R$JJNb;m#8=)xmf4VGs8rY@) zkTZmT!m9;vPLUY+No^qQ`fB2QIZ^aBij;BjQRs2@G5`S0U^d`4x^i*nQKIg=E^0h& zpSn)VRN(^Wx30Y@jl2)RgiZsOo0=B|W@;&EyF7w%LW{c7YcWWNSsNF@UcH7WBr)I* z#?hm8KT0$funVzzcot&*Jo!tRj9Zbp#4@JFF$lx{9|r7U+}W-zC;t`&x)Pgu5D;&ZEhB0p2tT% z$j_{;?Eyn<<`H%%?-c1#t5nCE?X-IWhmB{ao}k31VtcvsfA(fVQLzxhkhr+ph6-A8 za#l*$!~~o+Q6s9Be|Ks3EQBlGIf+Y4Fa2$eA>&eD@bdC$2%r=DQMmI$PHuxt_nj0# zepxWa12kiM&b-R){95mKsAgFRbIz_>-Vfy@OP5~0JSL%}LcCUls_Zv6#i)fGjJIY9 z0R4OZyfESx(o2yfD2<2JPfgiYRk!;3HnXOM*@@D#eyX(lFswT|!ktSR%zZ*ZMfIcq z%H?UmBHr#>NW&q54$erhKt3jjR!me+Pwzpm-K$q$GBfk~(w3I50_HSQacK0@foXfr z36E~=mU_=u!%t+_um6^tIkH0B`c(Hzvj#4OXVcqU3=AiP#KhDThjdIi(%~O^1}zzf zKPa+%&k~gHjgpx5?&?4yn%LCF`+8_KjC@-bE65h-Uy`vHwuIxz{JUr?+=^ z>kp9Y#NkE~O;Y4Hi?r4I zgC)__odOQw1H3BRV`Ws`-DeOobnDiwn_gYK?K5R&lktx*o12<&Fh4MQJvL|K+n?B3 zyaRK|-3@Xu^;Eccp`o}dmhwD%5+)5A2(r88x@;(D5RMP0?iu4veNO|dpIp!E$k>oy zEhiJ9-|Fqvf9C@8)`PK&x+NcQ%LmIpdcUcyPr@<#r%R<5IbHg2&1JrQduv;Bvym=n zw8#{CRXw%Ac%YyVnVO6i6E7|fL!nsbE5w7g7s4p-((r@px;XZ`fcwfu;)oviXNW+P z*FO4vgE%`ocCR8>)LZRgR~5h5?5Aj(&AyHxn2XTZ)`{F-!%C1=(~JkVVHUIm@?IC4 zm&AW|L=5?VcD-kiT>kn#YP(d#`p+KhIrq=TzJ;vwxO}levruqTv!Gwxzc38^*LFB|{ItDu!owU&sNs?q(NPzuVI9%?%aIdTL?F6gO$h>bejky*3I_~ikk4={|K`)(0ARl|s zztn$>g-m!yB#&94UL@fb#N(Nn#>Y=qYzO)Vc3{fN0@n6K=AJC( zaKXG>u1><@QlOn(EI7@KLjdw>ZQLa^)D0?v0@Z9$AP{mCr0Jnj$l*Qy z`n9~W@=l|KmgZWXH{p!|X+$vOW+KF2txa$^ot7U>{gQJine)bR0?xw7s3wg2x<`eU zD)-A*$A1H>~yOcIY3IyIw%N|y61$zbWPZStx9G`5TzkYR{ zfvH2xYAOawX|rJ)x%^?!kcgh2REvtZ5*9Bkse)&Xk5{-m4Z zZ@+bbg(0F;)ZT;vX|TV>7#>bD;W9WkUAIN&R?#3F7UTSco)E%dtGpi`kBpR8R7{$f zEZNyTB9zc5>N%c^Iqw@7xRY%@SvA#{84G*`xi(7SA?w4f_21Fj#kW2ZZmpL5j1nCj z#Idni+jzriJO7r6`TQ}adbMaFU^|yRx|%cDk+aq3zdDXxuADON7j#>#DNb~c!XM5xF}4A z*^sl-b@Pmjo#+G(3|?^WS=%g`n3)BK+7321Pc${r^YBa#48V$ohMXNP5HmLu{3!b1 zOrU3Nt{vmC)n7nyj|B>)OC9Xn@25) z-+<-lK!)47I#6C0mzIRz9h|@l3p5ohWOCdU_eZEzCZny$v}Dq$(Eyr8vu5UmPbW*? zR@K${#7=kWPLDh1=O&ytlS2q?W*-myTp#(aRpy(vXjyd_q{vd?dKw?piJ7GM2JR); z;DQPDUJpQ;^gIT^>xn9D5}Hb|BjDddGSS*EypTDgH~}A|7r?=Z^v=)z-LUp8m+TYm zDsYHfC4D&|bb0Fyr(U~GMQI+K9n?C&av*Z|F2JuRyUUVTP-q9D03l5@48et^rQ3CH zU}Yhes9#DDrZ`^cww*h{O5>q>H^l&Vrx8h@uP3P&VAKW~S#P&nxd;I7zN_CrIX4Mg ze?;ubjN>E?be*4uZObia&gT!JQs%|zQ%7C%bCzK?`AibRzI1b*r*bnVvz**BmzhttSrX@2#PtD%#ubtlnKS|F)z9iY?fXNPR`J z5b~-@n@0evR637lmfu7qI#?;7v7mJ*T{WTv6x6b4<~pJf13Fl7&4a_kJH+zjStS4MYz!V48gYzEaRBdJL@?_v{dP^G9 zw6uKrr51*$X)g)nL#1S5UU@1iDz#_N?i9eKH!wIz{1I0Tp!(cgt`t}O@g}ohyM6qy z=|7!*!>@RcnjB-vbDZR1iFA@8%22SkP>}_!c)tjy0MS;n9|H~%)Bs&KpfBnctn zm6K!eq853}3vSZWyO$6om*;uiv8QIy6|undS4yf8u-B%X@ZjL7<`jw+2 zmM&M%igN&M!ARiHf_^$S^38ixH=3GA50_<^Lz7h^C*h2Es3HmD`QFMuGmeygBBELX zYJN-ond?+P-DVnoyxt{1loA|+tqDnxKvn2R>j2v2sECr8gfi~ob4F%hK>k*6K_JY1 ztoaph0+50y*~?q-Our5t;SGJ_?tAk06qTC)<^o_uV@Ts8G*CUEJNJh*?W+hQQ8;Zv z7k_u^*<@`7zlep~F5{-wE?KF)t`@O>0StW>C01V-tV8Y@Qu7PA^Of^2eQWH#t$iVtk=b`bVs0gUw&mJqI z$Ya4sNgqPE5byx?1=n6IBzQyv4Hi;k4B2iotlv`j_m~;F`$wP1Um6+$j#7Pc^3Hn) zuT=I7$(Ol(W8;#0EnFBHR=_mc*a$xA8eLQR`wz-*HrKh>n_dk?<;HX!XoNtn1C5D3 zTNC6ZID&8k=&2w|0?jiRUUWv@kvzk9XEIi>(?`}^5|;&}4Bx2Z`V5QT2zc}=Dt3L9 z4y_L?F?|dfIB>@e7Z{F@jj{OII5>2)wwjLgc=%5&iSv1HY-;=Ac+qT+&IgT5`9 z<77`W3dW#7<_H_JMJNL8X6jSg?@|~w6NnywqUsX77R<`qqOt&lZ%Y9&&kD-#pIwc? zQ10<#eyb_>fB<=r&j4*OX4pxQ4?D;LC~Flm7``Gt z%eB5i%haK}PwD>m&Nmg}?2xcdxa=t`ONQ;8>=rNNcvEo1ZLAcmr(SsxMyJ6nXmzv~6G=hgbm>x_ znLJ;~#PWdmcijXHu%m2(Rlmp=$W+mihY?q=y|S>F0F9Drw#MfYYG+&P#kB=~?Lr2@ zk;(qMrMlHo>grcJI>v9@C^j1xJl~l19~e-stK(y4c<@2BxOk1x)9y2+ydT=MqNfVm%XZBGUB3gzb@mM-A$XX zdHk&a{bz=8mam(_KjKZP>>I;3Bte$ZTYmjSq#?=j8WUjkW_Pw;%l z9=trjL#SZFt>AGQtunt!u1In>$l}T(9-7jS;2Z(R8j&2AZ8>`KYa=R%+0Aje}1sk&)z-EC`(exY57I;5<=xFY#WIm zXNNV9{u`4P7-~;t$${kqP%zAEK&OTe^FK_?sqI7HvBHf9z;O(aVStlUS6d6jk4KoS ztgP4Ar%Bi16>$+uz+&YM9di7dk}?ho@njaA&iH%4YWw`1j-)UR>ScD-D{Pr=T1@jE z7M<}T{y{+yJv#)|5BP4seEAZoenZ0z+A&a6?)?J*gV)7^WXhueHWn8Cw>w7S;^M#! zfp^TT&JA2u@9)t>K9di~e$jSdA~uSlOwf<|XMWCe+9AZ`6}&o179C9~n+-bfiGp-I z?pRz)XLUl+goNPWA8?ofUgzGH3I8B-q54F@#b#z^^6~-CKS6uBy|wjc^9>j;|N8X{ zfZ;Eo{^z#IzXMs0=EQNXMB4q%S2DA z(0?W8Nnk$Qe7k$}iLmF}pyA3JTKH-2#B6V6cWq4<{YpK64W^?GCx8!TeKS=l_Tk9w zMjJQ4#K94=ox@G&qyqseuw|ftWt4re3@E@T>@<^;ZopVlS64SHQ)GdrZf;Hiba`M< z4_sb8%ZV_Jp0>LW-O&&hzxb(*zB}*B3||2^rKe)m-IqNS=?T4joi`6DWFyv$dK-SI z<#Ix`d)O953>d=7iXhylO-36q{RiD2uo<7Js-~trg2mVEXc36VMWbk=C#^kfOEMKe z-T{%{lX&5eK|zj=j-5?S!M9$rb7>SBfgiOOAsU(|$Wha}fE5LzRbgRam~sk3gSRm) zHwh9>Ce>P{C5MOPh$+I89WT-cN?}=RMGuvPg?@Gb%QyP4w>G&lGxLtKu-5%wE^32O zfY$V+uKVCFN}kcaK0a0ya41*H?OYpYf29g@RWMa|KG^8WP}=6wYSJg;HH+N-?N9aW zhmY6oO30PaOB?3xnw9MfWYZc^Zj8A=Qj*0*UXJO2Xw zWihY2h7*rq$45v(ncXE=RAdhfQ}E2Nwq2$nFFkTQcdiQq&u|E7_(0f`7Vr}A&Gwie zh{w@y9v&aZI6XVA15CkUlGDaMuFP?rB6Y7yIudP!K{nbUF^1_roK9%{(XzKE&(lth zmg&B!w!=Q;x-r!a*Bd4>!R6i@wC@*SGISL3EMEy|+X@R;=mm~HQP3ihpM=04yGWbZlL@B~ z?#ocx@p`S?=byc<1Y?85OQ=#0sJ&8OC<2pNc&?cx^|inn)~*}7g1vHs#I?DrWT|3{ z>p5H50|i~)XQs{k_b=%yB;Uq_UF7~33SeUtN?cK9aX6+?m64I*AsbX|#n$rL(nKfp zRF;1w37@w8{M zhDOWGrkT0?sVKEu2W^uqw&MH{px$3?_y7Y6oWhkT<~zfn}@6%6rdJ+-wr zfP*+VI0)Y`FnGCuu%!$*ZVom!us)J1gP}wMFkiZOIS4VoXJ@yzw9LL$VvM&nGFCb_ zS~#?<#YxZHFat81(%&afyJ;MNY0<_=#Nr1udpeh$Zg_)gpc8)<@|J??ACMW)-+XBUt3!0YH9+o5C%IsF!RMgHT~P~x>~Nzmu{!#;pXZ_ECzP4 zetl$iok8}i11Nxif#|q8(%;gu1S)bM-$2El{q37REeJS4gKPms8;GZ2&d1^>Xt&Vy z`KA=uWP=16s?0ZwJ*jDx^`*s+{X^d7au{KvL*E{nu|?bt&JN?=EqbB`Kor#0(z-)w5rghtW+hW{FWm z6z$ko-UB5TqC|fl9v*@SgI69>73QGUg()AeJlurQ(a|jn6|*a|le#=1*DES3f2)G< z!^Ahrs!eP1OWccy=j!UldV1ht0lSluwsw2i&dPAX*RSBk!w44>77mVSt?Vb)WnKPDeIAKq56{cHgM7e3qWbJvH!lYXHuS}e^RVLt1O@Tky$cM`xZ5w^ zf5Kl_UM}e6j*bIu69`t}LV5X~sE8kI?2zwW|AWsdt@?r#=>|^WaZtI? z@>yuXmW}jEGlnogFik`W=pKoSyRUS}c5oIOHDBB%Jqz3PtO5d2X^X(>#izRWi31GJ z|FnEz2fqaP`fGfJSGqM$`|CT@V)D7~PTlW@2G@;W7@)8PLnT}+td~`?T3TAvG&ESq z|F8Cdk^R;`I}T`ciJ2ATWMqh(!?e9l+8;?t0X(|5JP3IJt;53tH*V+w`_-3#4z5{z z0)i)x9}}9Yf8P!%@aNFTe?QCiIGp!L_%RzRYhHdn3g$671y(HJ>^=g_XuP=cy&w|e zmVplQ@LiRsrzfb_Dl1RH$N>vRjsJ+3fSClh&BqQ-^<*YkF~yaqd+{h4NU*_I0?6C& z|LB3spvf|p=ciqRxEz=qPv*apg-Lf*0)-x<+=B4}HT_(-?Ra?@6c7*)7CveEeDkJMpqb6h z(n(LECNX>nbeV+FsvguHz<7S8L)lEU^ivhPkojPp%>m3vqI;fs+6pK7RZ?^Ju8D46tIRsi~=9?XiSg?fG*+ zur$B`3;InzfkP;99f5Zaf+|pI9?gb60kQz2tcKnA#SRgW4uc|uxa{Y)JOA&+2v2$| zpaQtKL$>ab#CDJ_1?62GOl}D1I&i1Jjb9!m1=ApL&62>W<=2u8y@TI~p6N3&1IPI7 z+qe0$ls&OdUl6btCgK4A;*L&4gJo)@BFAmhOjjGtV=0R|bQ~VI7>ULVk}-QLV-Mix zRn*T)lzyfo#4~+#&ehz9x?!*)0-XcClt_Nd-BQn=&DMC)Tos{_!gEi4+j43S27YkD znH)isGtI|dNM9sE8<_m2&Fihh6IZ>)y1Pdl>_@JaJMID<(=GJWqn%84L(nBAC%-@4 zhNBI*q5Si=#IMb2Z`p9F#Ls&qX8@^e&!+<+4kLJzCKR4_UkQwg9AS(Erl2V5loc}Q zLw)X}J9nwFJ2|}%nGIXzUMVX(Qc>m3&eHu|3F)J~XHw_m2~#Z{$*DiLUU*$jNw|oAKCfm(8U&tqf9NEG10) z`wb1$UPRQMgr>`P2gZr~)zIpukg8>bKes(fpkxdE{638tTaG-9-UTko`ga$yde6K_j z0L>mYqDpdihh5-#eZ0MY!?q7t5{&VBdV0VL1zzOV$omYGL-wS(fGHauEb~0WZu{%& z&gZ9&ApDI0+N`jO#@paV+q|N?P-r=BZ#i_?rIqYsUW^QR3FPX&KYj!m3qm5;3_LoJru}=ikn8RjI^@@+vY}Vm>O9Uf4Y$*TIW0OsMU$+} z==I>#)1~9DTfw*Kd%e748rO;5EQTz*4=#DI&8BuhWx+N~g7iA9Ac`}}xbF~N zvWh^~LlII(fKqwYL6sJHH4i$Ag8Y0qqohPcHx6xn_=k?Xf9|5MKLZo8&?r~%vjEf! zPEn$<#;bL|tt}faF4&t;UqGXUA1y5{QHKz1SWv&=lYr|9KkAI3+SL+^aj0-3;5LA& zAv=5ZXm>fv#48wHb#JlPH!9pL>TKVaNxm2SV;1_qsYO7&3uS9q7{dUc#D|20Nia?_ zj;^wu$LFbf*lTBO4EIApQ4y*RgkIMu8bYPZA|liPCW2e6`e=!L&sN4ni~@F(v7e5) zM$J$+Nd;0jbH4rW_3e$aF<3|gsRepq8VY*U!5r-r<7k&XgWTwlkFWS09ZO)O3?i*? zj_pWzca*@05$}xx6HtKOhP7%HewdlJKZ(<*BY|n9r?eT+Yc-2{QWo1JeXDkNX@GU4 zmfJu;v&1lhkE|aWO8jBPC2vT2eX}vhF*Gl%scDfnPQZR?;{)b;dHMG4F2%KL6FNG= zX(L(BcuY+?WN0P!VH*7Eduyh$X-f+}P<*+EtzjU1_pYI-X{WchiyWr05vPMX-MbCi zm{p6hp?mL23s!KY_y}hxT|M}NY)z4S*7XYHNMzhMqb&+>`GG+Xp!}sBjJ2qn{}&D{E@D zQg_$3aTX=u0?v&pSi)g$ouAO^6%6v}B*jwDLS4K0=r&_WE2<=g>&`e@K~@$euyyMX zle<+1CLUna9mE?4bn+0Vrly5+0xM{jugR)~+%#xQfit159s@u(ArW^}rk1)>Pi?Y` z_V^)++7rnVJzY`phR*fi%m>dlM_ZN|9PiO}7d{k@V{O+)j_ehHhQH z-!M@r3*-Dp4dp-bf-+&yYCV@U-x)+KK^g6@tvXuV&=&frH!4>rH72Uan76K*=#Ii1 zPQAI7)>VlQ;`E7(q7e(dDjb*e&zJ_Yc{PsftC2OGi9 zec+~Y-iPv}48(W7Wk3Cc>ZCb;H!bK=bTl=I7gi13Dk_?XhJsR?>~-zX!8y;EKUpId zGJigKQO+-UX_+T-5!hm{)dODhYcMq2-Mef}E_J;A=TFZ!HMn+d7eV*{vzEf*Vp_ne zz{`=zexjts>M2#&=V=2+cft^`gEd8cjRL&a*Qe4grLV6KP2B`+9=TOVEns9bQQ`FT zn6>EY9@fjShzMsWy^f#4NL;~ouL#{piS1{h;OTnOWe;(B^>k=AU5@uE?G}3g#Df@2 zOqAXYN_y1P77q8HnVDgfLSd^=3$Apze;j{w%4`_#-78K@V}iI}vu=>&!@UPJCESGY zy<8HCla|HJ%lp;%2%LbvPJf%`>w9uB8U`2=hNzl0M?1!Fs`BtbSNp@TTb47TY>|K4 zNLu=1XehCee#*Bri8>zvNbF(bwQGqNF&ql{pUn3(Q10imvn&D=?f35!g}4a;mm@(` z3+0#0q(Gf-^H)c<6(1NU^-KHzOC>eY^%UkHKR|U88Tmq@$?v-J*!VcZ@(-Y$5Mz6D z5B#0vAkZql#mZ>`as~yv9Sf(qrJ?SX{%?aYWoGm`Ih@yx6O3wJ_{1`2e9c+NU9hRO zRi9}{%{S^tNr~mo50`En|6sTDI|5W+8TDdgXH%q-AHf0}lmdjx^f3NhZhg!U70t4r;w|DLn(?5)1yL;+ za20}uTyz>hIlr|i`fF-l9B%yuj4c`G6(zU{EsYc{qs%z6HTlwJLEi-8Q&>U^A-YIf zdJ)c-lhYwM+vRAL=@}T1kdi`VwZ!XUi<|mjPLvgF?vfIDAJP5iYfB#mvEQU%S zDfOKkZtt&-4uYuze1g4&ZqMWlXoCGYN=i$IIy=_^sWJkR5S;m_mlg1Vs+_i8Z~pns ztt#JKpR?%UPo9blTI zB&QKeBquw78_ZvzFS)2Rh^+tpHBMeX9*>4#!4}2nr%A8=R?n@a*cIIoH|lb_JI}7R zR`%{N;uG#7*=6(hM{n;xYUn&aU7u)c3-B{hmIu9T0A2M#TU3!(aGpL{tT4s5+(|zd z6(JsKDaepce7)t^~ThOPgqe|o9^pkcXE z1f*MMXET(!jq)IO6bCjoux31Q(+2<~%U?t+L)R<^aPOOfJ>+V|%#U%k2u zONRt_5&k0=|L>}A<@`E8bfAd}F$1)p3{YH1rOD6BQ!lq;)zr0&Qkss4je_N}y%I$bK*McR=FWthU^+GwisH;ci=B@*K>sOc=1Z}|01d$~`^?^WjMS(W7;>1X$h>>IE5a}wy5e+sP1mJ9N{Ob(J2?2%2Wi?ri`&;fp70*H zW-g7DyiR6;wCbMv`mYyRoJ(%!$8_7)n_!PIUg^vyCMG5-8lSd!&wK>71F(7VN?U|T zoZfSYdQ6Ef-x6_O_wudrsKp%cVerc0sl~i{^>gvT5({RNKDJlX(pXfEAZdel>Id!q zQH7)w|A$4F6|VLz|Fp{P7wlD%)m-3ze7#7uP)&uJgVCKp=k8P9VB5XZ8M%TUh8MG+ zt(x`=PV}Agw}q-JGt%FGE)U`4o;nlgDAuJDDW2hmHXkw=Zv2}V_uTaMB>(EsANIML@WUw3>6g>EUDSQ4rp=pP%q=jNK0YiaVhX{)^4jacHTvMm-8bdO$yGREra zuXHAC@}8?GZ{yKDD0$q#XLkyw3T$5lxYhIJ!oRD`6_!l?J%+8PeN>2*!@M_yak-*0 zRP{Ry9#@8y?>KGYh>FVSPWHWjPk`64yh1&!TWG($C!N~Nu4XZ3J5;nB8X0L-MMFhZ z80JOyMQd<+_B$bIfmD4%~q|DtPYnR|#vK_3|S%Z=z( zYxD~G3(1UKLJ0`z=B1Peb0%|hj?^8fH~@4E>w$7V;>#B$nP+TYJU!7;RWeo5Qd5n2 zqhS^K^a)p@2{t|5H`7;T7Gb-BdBi7AWf|ZWL4OaWW1)sQ5c$C7>V5*4BLvRCE6jB! zSjIkbivvodyu(0%(bN^(^8UWQjjKig_{*f`mz1Q3Q8x0$d%QeR|3oN(nc8UYrl()W zXQ?B-xXGc(eHcMR6rY{Vk+gH*jUyx>nZ7k{w=QU#rot3cldo&=nu$x7)^H>1{!IZV z3)S%a++3M&r#IMTqe8Y49u`GM?`vq_Z{dAel5}}LFmV5lmU;-_3GXeK2=ev zw;mH(uPAu&>+;!$(9mAM5Li>e2*ispa0co^6-7mH*6i=!XSpuJ-0I{rsDOXh*DoYT znMF=Uy;27!h=BoB8Av}>JG{!{>2>I1-3Is<=oJDU^$rd;PU=gsUibeEc*BV}OX?hM zy#e*0Iq z2&Bc(IQyHF{Fgi}s2eGGw)eeN&q3Lsi}#)qnej*VoikkKHQ>8^ccH*^kW&T@+agS%KK0%nc7k8P^+2%N z=4^C%4s~=0!v$>L@2zCgd##M_N3AstWS`S}QH#FQ8_vfokEd>Y_RPiHka=x2dzLI# z_4|RnlhbwNgIlDN6~mjIZfCPT4^gjMH;_Bom`~kmvplfsAAm?2QkEZPw(|!yS=~PAHVDR%|E^~m+L#~_))fghnj3(SX=-Zkt>uI91q3Q4_r=*}&V|s$d-&4^8x17xf=7EDyRuI1 z^h2zK$u(+f*M@~IYAJcI`e*&EtmbnV`XP-sy*VMXpIbXRUanMnI~hT*R{Atn=kiD8 z?>CN5zC3@v4`9w&Et;_U=8>*4;U6~Yi3_8wb9w);j@R8n#b|K3RcJ$YnQ?`0Zn&B{6l2-ei2F&;6&o?iN*BzPnbltFXDq=d@ab)KIRHDK7g++O?V zlA9@;e~Tv(l+PCTH$Us~Dt&?s31Hzjasdolta8x?^$E*MgHvx@OcySgj4JI^n4h2D zdO<%hPI$N|zv7Bb%Z-0pFr(&36FpW7%DFf|Wn1S@zt5gMnAYh!?E-=F9e==UguG(0fvRUyk zLCC0*u6-#6>!v*nAlSOLkrD)D(=p$5gj?qDn>{4*FJQ$e3m*nB!avL|-q6;n#$6JQ z$6=o;hG7reLp9EeA}j@CQTL^#sl-{0H& z9@OD*cS(fxlShw|g36;FO-DJd_1f9Uekz~b+w!o8^I1cYbR(|vRVJbRkofrMljsr$oyIljQID)ai-oLKA4P?aD!u<}{Cu!-+kEXxEaVi1d*FT<2$QpR%$AR<&6UqG7T4(?EM7~FzY*a=6rq_z_a)|nGqSRrBY$k6leV-bStBy0SRMM zhHlQzSr(V9G?NfO6wh8RE7M!EruG*u`oehm`Q0ijTgARj)!C%1Pml>iMdDV|yJP9y z+dS;Xp~*XN)iJ-IV7->sYfrPaviV&;|90kdR*gfugri@jzB|?)K6(`K4641=k)TR6 zOV(JCKXIg@8gJuE4 z=Amte3XZXY?@PK{T895CKYW#UE@UawHd!|Wu6EaImc;gg*j3L}s>`?0j3_&Ef3{)* zVvMvHp-@4At77`o@tX3E!+@4NZwnL@7b_9-zklpuN>H}ZLg(?jxUkj~`|hy3(VI*q zvR9v_q4MjME2nzPab||G)!(z8uIsQGMOIt1-}iQkru-QP2Zu?oX$>iCBv4Dp%gI@? z&@;llm|o%4t~!&8$vv^OQ-6l={56rfZe3npp6{k~pe~R^$7c`c{@FqKYrYPAM?Cc? z;Vqn(xffOdj#}ARtH9|a!o$(BLL>JJQGl?6unS87qzRamDCS1+4nS!wSx=ulfoIK; zeUzJJWu2=$bpeU0#@z;r#@h)uo$>eYD^YofY#%G$*0viQ(}y6hg9l?yojT9T#Q_x3 zWL*VLn2t3IzH136`snNH>+J=~&L#QiC-e@{&3b>9;1k8ABz7h3Rzv)@ z&k@Ig1y^u6_sgY<`102;(ZK+hctuL;DiJYKG{6`!>If!`X>rhr*(APf7GK&DKKcY@ zuX+zb&?Iz~!d3?=EtipL6BZyoz^)A*);ER??@Jzn(kSBCnyO+Yf^D9|m5|AT?0ogN z-;N`sem;s;3ifw?M4RuYWrv=AdoKtPCQYbt21Uj45sK1VLgW@g0kwYqfXuRGeJ@^! z2d+Pxb3%O`v^#2%P>(HTnya=~j#RCnP|7hJfQ+ZGnTtf2RMY}GIB-4|xI~*@gi$QA zf`RR5=aybwJ$nF{SdHW=z?|#lP9tg!q0NW7-B}X&8FaNU_fHG5P2Oy@0nBhu4y^(T@u4dWVKC zBq!f;Z;%E3d7`GYq9PPPCssbn13@b`CsQ`z{(PvBYYh!l z>#7Q{%)l98L^+9)1eG7Oyg*H$>9djW+f-*Jdco}3wd)(9WxfrZr4l7HEe&-x@{WhhZB%>75Daw+rZx=)klXE`09#K405z4BO?PU2@tUb_4W0r z?T9vqER9+QZ+pzp+qXCE ziyG=h?YzoL1+MGYA^mb9NDn~7oiJat#tkt*lQTGNp!U2xWDH5@8Wr=R{aB$_uWB_l zFTjRBZcP$|WKN`pJ3=hJ~zs{KzfDZCj#Xn0uOb_EKzq;Km^a6m{Bp`h3ogI0UVeMin-xpD=ZO>=YeITH~o@K-|Nrgr&}<0_t4V<5~Kn$4E) z!Ty0P90>!YG#gA!2{yH`mIQm>iDqP25liLevH!M~olP;=198~nYEHGI77A#PlfGQ6 zc&$SEwwI!uTw+p^N6SU*231uiG}^&7x4FbOd^HOHpJ}0{nGGiDJ@XGi6NU6nEKB)b z2_=J|YF^aWM*$n&0Ag0=#m74Gp^MUaN-y5d)EF&>YhNyxP} zV2+X4wmnQTdwt9|^q|;O;iBdPXk0ZsJcBWIFkI3JonQX`g2|JyB=*C*Q4~Ix^3Yjg z_M=rLT$9yY>C5=s(S0WA#~Yd($@7#5zWUFK()?Sgv|e#|m6Aqy&2Y067~j->bM0;K z*&U||Vw5paq{z1zY^3WP=po1UbdU(P)A*yk1W{-<>p*JeG}ZUPIpEyfHvu>_-v4R0 zBT6(1rSWc##b97lw$0jf&&h;2L>S4aQyk=18~rEPAIm33>me$i6gc?b@p!(QAP&ku z`fDRVQQ+t=fSHkEDq{z5Gk1NlHO?!mCL0)*sgDvavxOrTs%8X1u?V?LV#nAPuXdjr z?}|KcIulrXFWMA(A_Wz5EzYwip(KKTioaQjPgx=}`s%tzNmKHDS*DSZu#U4-IcxaU&46d+Q7S4;1qF1YkhYAhD(~qDeb4^-iHXwS;Uj|=t;&eB{WgP9bLryCm9dxVV!P0= zB=@&JeVO%lju~ekKb$Ue-S7FXbH;+{m&-F&84dJJ>FGWX9V+ceO|^UfdY*%hKS2zv z!Z->{f`ct+^6=TMT(DqvXuzxbhX=AV`gK;!Q#;mb56t###nG+#(sp0`$1Lr_dYt93 z|ArOm2M=qixHrlT=4EH8MOw1tX;LbYh0ac*vg$5#^e%h+POqxJm7`^NWZ+Qry`a9v z2ec-;jh^_{#aKQLV}cd4x~}2d?VnJSJ)9gf(=(pp?D_Ew-2x($nej6J){N!TEr#^> z#@keJC``Si Br#}Dy literal 63861 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

        9a@9G8c?^g05 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 p8O!*$IWPGCfBA*~=Sq0nu6^0_G%vjb^PeDg{
        Artifact Cinelerra3

        Depends on common

        Depends on gui

        Depends on proc

        Depends on backend

        the main executable to be built

        -

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

        +

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

        Artifact main

        Artifact source

        @@ -379,16 +379,17 @@ Documentation

        abstract base class of all MObjects representing meta data or processing instructions

        Artifact source associated with : Meta

        -
        Artifact chainplacement
        -

        Chaining and additionally constraining Placements

        -

        Artifact source associated with : ChainPlacement

        +
        Artifact locatingpin
        +

        Chaining and constraining the Placement of a Media Object

        +

        Artifact source associated with : LocatingPin

        -
        Artifact fixedplacement
        -

        Artifact source associated with : FixedPlacement

        +
        Artifact fixedlocation
        +

        implements fixed placement of a MObject

        +

        Artifact source associated with : FixedLocation

        -
        Artifact relativeplacement
        +
        Artifact relativelocation

        Placement implemnetaion providing various ways of attaching a MObject to another one

        -

        Artifact source associated with : RelativePlacement

        +

        Artifact source associated with : RelativeLocation

        Artifact allocation

        Artifact source associated with : Allocation

        @@ -636,8 +637,8 @@ Documentation
        Class Effect
        Class Meta
        -
        -
        +
        +
        Class Label
        Class Auto
        @@ -646,7 +647,7 @@ Documentation
        Class Parameter
        -
        +

      2.2.2 Package Builder

      @@ -911,7 +912,7 @@ reuse exiting Engine

    Selection :

      Transformation

    • length = 5
    • start = 100
    • -
      Class instance

      type :RelativePlacement

      attributes :

      -
      Class instance

      type :RelativePlacement

      attributes :

        +
        Class instance

        type :RelativeLocation

        attributes :

        relations :

          diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index 28aa29de6..5984e789e 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -49,12 +49,12 @@ Assetsclass view ATTACHattributeattach subject to anchor (e.g. an effect to a clip) au1class instance -aud_Aclass instance aud_aclass instance +aud_Aclass instance audioclass instance audio1class instance -audio1class instance audio1class instance +audio1class instance autoartifactMedia Object holding automation data AutoclassAutomation data for some parameter (i.e. a time varying function) Automation Entitiesclass diagram diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 70cc864a7..5ed3d76c4 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -34,8 +34,8 @@ buildableartifactmarker interface denoting any MObject able to be treated by Tools buildEngineoperationMain Operation of the Builder: create a render engine for a given part of the timeline Buildercomponent -Builderpackage builderpackagesourcecode package

          The Builder creating the Render Engine,
          located within the MObject Subsystem +Builderpackage Builder Entitiesclass diagram Builder Workingsclass view BuilderFacadeclassProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 2f29cffbf..198d3e6c7 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -25,30 +25,28 @@ causeattributea copy of the first exception encountered in this exception chain chainrelationChain of additional Placements further constraining the position of this MObject chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. -chainplacementartifactChaining and additionally constraining Placements -ChainPlacementclass checked_inrelationchecked_in objects are subject of cache aging and must be not in use checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging Cinelerra3artifactthe main executable to be built cinelerra3package -class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance clearoperationclear current session contents
          without resetting overall session config.
          Afterwards, the session will contain only one
          empty EDL, while all Assets are retained.
          Clipclassbookkeeping (asset) view of a media clip. clipartifactbookkeeping (asset) view of a media clip. diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 94fe56f77..485f245e8 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -29,8 +29,8 @@ FileProviderclassThis is the Factory for Files, whenever something wants to use some file (or temporary storage), This Factory will hand out some smart/shared pointer to a File object which will be used to retrieve Frames. FileReferenceclass filesrelation -fixedplacementartifact -FixedPlacementclass +fixedlocationartifactimplements fixed placement of a MObject +FixedLocationclass Fixtureactivity object fixtureartifactthe (low level) representation of the EDL with concrete placement data Fixturecomponent diff --git a/doc/devel/uml/index_72.html b/doc/devel/uml/index_72.html index a26e1439f..58b669cd2 100644 --- a/doc/devel/uml/index_72.html +++ b/doc/devel/uml/index_72.html @@ -24,8 +24,8 @@ howtoProcoperation@return descriptor how to build a render pipeline corresponding to this media Hubclass hubartifactspecial ProcNode used to build data distributing connections -HUEclass instance HUEclass instance +HUEclass instance diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 496421c53..798945020 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,9 +20,9 @@ idattributeAsset primary key. In Memory Databaseclass diagram inFixtureactivity action pin -inputclass instance -inputclass instance inputclass instance +inputclass instance +inputclass instance instanceoperation instructionsrelation Interfaceclass view diff --git a/doc/devel/uml/index_76.html b/doc/devel/uml/index_76.html index 8fa1f472c..9b41469f0 100644 --- a/doc/devel/uml/index_76.html +++ b/doc/devel/uml/index_76.html @@ -25,6 +25,8 @@ linkartifactforwarding, adapting or connecting ProcNode loadoperationreplace the current session by a new
          session loaded from serialized state. load Mediause case +locatingpinartifactChaining and constraining the Placement of a Media Object +LocatingPinclassAn element with value semantics, which actually implements the placement of some MObject by positioning it in some way. Lockclass Lockclass Logicclass diff --git a/doc/devel/uml/index_77.html b/doc/devel/uml/index_77.html index d83661f51..997d703b9 100644 --- a/doc/devel/uml/index_77.html +++ b/doc/devel/uml/index_77.html @@ -32,8 +32,8 @@ MediaFactoryclassspecialized Asset Factory for configuring (new) media asset instances based on existing media files on disk; can create placeholder assets as well merge activity nodemerge activity node Metaclasskey abstraction: metadata and organisational asset -metaartifactkey abstraction: metadata and organisational asset metaartifactabstract base class of all MObjects representing meta data or processing instructions +metaartifactkey abstraction: metadata and organisational asset Metaclass mobjectartifactKey Abstraction: A Media Object in the Session mobjectpackagesourcecode package

          MObject Subsystem
          including the Session (EDL), Builder and Processing Controller diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index 7a0c5e875..eeaf4b78d 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -18,7 +18,7 @@ - + diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index b34c12000..2a52fbc5c 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -20,8 +20,8 @@ - + diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index 40cc37dd5..3a3a83808 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -20,10 +20,10 @@ - - - + + + diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index 5c1a18530..eb3719cf0 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -31,8 +31,8 @@ - + @@ -46,8 +46,8 @@ - + diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 1739030f8..03ef3d02c 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -42,11 +42,11 @@ - + - +
          NameKindDescription
          nameattributeelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique.
          nextrelationnext additional Placement, if any
          nextrelationnext additional LocatingPin, if any
          nodecreatertoolartifactcentral Tool implementing the Renderengine building
          NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render.
          nodesrelation
          offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation?
          orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core cinelerra-3 codebase is "cin3".
          ouputclass instance
          ouputclass instance
          ouputclass instance
          ouputclass instance
          OutPortclassstructural asset corresponding to some port generating media output
          outportartifactstructural asset corresponding to some port generating media output
          outputrelation
          refPointclass instance
          regoperationregisters an asset object in the internal DB, providing its unique key
          registryrelation@internal Table or DB holding all registered asset instances.
          relativeplacementartifactPlacement implemnetaion providing various ways of attaching a MObject to another one
          RelativePlacementclass
          relTypeattributethe kind of relation denoted by this Placement
          relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one
          RelativeLocationclass
          RelTypeclassthe possible kinds of RelativePlacements
          relTypeattributethe kind of relation denoted by this Placement
          removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB
          Render Entitiesclass diagram
          Render Requestactivity parameter
          Service Componentsclass view
          Sessioncomponent
          sessionartifactInterface: the session edited by the user
          sessionpackagesourcecode package

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

          Everything concerning the EDL and Session, within the MObject Subsystem
          SessionclassPrimary Interface for all editing tasks.
          The session contains defaults, all the assets being edited, and a set of EDL with the individual MObjects to be manipulated and rendered.
          Session structureclass diagram
          sessionimplartifactholds the complete session data to be edited by the user
          SimpleClipclassElementary clip consisting of only one media stream
          SmartPointerclass
          SmartPointersclass view
          sourcerelationthe media source this clip referes to
          sourcerelationmedia source of this clip
          sourcerelationthe media source this clip referes to
          SourceclassSource Node: represents a media source to pull data from.
          sourceartifactRepresentation of a Media source
          Source Overviewdeployment diagram
          trafoartifacttransforming processing Node
          treatoperation
          treatoperation
          treatoperation
          treatoperation
          treatoperation
          treatoperation
          treatoperation
          treatoperation
          treatoperation
          treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated.
          diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index 0ae05e4c3..ce992fef4 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -22,21 +22,21 @@ vframeartifacta buffer and render process holding a Video frame vid1class instance vid1class instance -vid_Aclass instance -vid_Aclass instance -vid_aclass instance vid_Aclass instance +vid_Aclass instance vid_aclass instance +vid_Aclass instance +vid_aclass instance +videoclass instance videoclass instance videoclass instance -videoclass instance videoclass instance -video1class instance -video1class instance -video1class instance -video1class instance -video1class instance video1class instance +video1class instance +video1class instance +video1class instance +video1class instance +video1class instance VRenderclassRepresentation of a Video render process. (Encapsulates the video buffers for the actual calculations) vrenderartifactRepresentation of a Video render process diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index c1e7fc022..4c0504594 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -21,13 +21,36 @@ */ +/** @file placement.hpp + ** Placements are at the very core of all editing operations, + ** because they act as handles (smart pointers) to access the media objects + ** to be manipulated. Moreover, Placements are the actual content of the EDL(s) + ** and Fixture and thus are small objects with value semantics. Many editing tasks + ** include finding some Placement in the EDL or directly take a ref to some Placement. + ** + ** Placements are smart pointers: By acting on the Placement object, we can change + ** parameters of the way the media object is placed (e.g. adjust an offset), while by + ** dereferencing the Placement object, we access the "real" media object (e.g. for trimming). + ** + ** Placements are templated on the type of the actual MObject they refer to, so, sometimes + ** we rather use a Placement to be able to use the more specific methods of the + ** session::Clip interface. But please note the following detail: this type + ** labeling is the only difference between this subclasses, besides that, + ** they can be replaced by one another (no slicing). + ** + ** @see ExplicitPlacement + ** + */ + + + #ifndef MOBJECT_PLACEMENT_H #define MOBJECT_PLACEMENT_H #include "common/time.hpp" #include "common/factory.hpp" #include "proc/mobject/mobject.hpp" -#include "proc/mobject/session/chainplacement.hpp" +#include "proc/mobject/session/locatingpin.hpp" #include "proc/mobject/session/track.hpp" @@ -38,8 +61,8 @@ namespace mobject class ExplicitPlacement; - template /////TODO: unsolved design problem here! - class Placement : public shared_ptr + template + class Placement : public shared_ptr { protected: typedef cinelerra::Time Time; @@ -47,18 +70,41 @@ namespace mobject public: - ChainPlacement chain; + LocatingPin chain; /** resolve the network of placement and * provide the resulting (explicit) placement. */ - ExplicitPlacement resolve () ; + virtual ExplicitPlacement resolve () ; protected: Placement (); + virtual ~Placement() {}; }; + + /* === defining specialisations to be subclasses === */ + + namespace session + { + class Clip; + class Effect; + class Meta; + } + template<> + class Placement : public Placement + { + //TODO: overwirte shared_ptr's operator-> to return the correct subtype of MObject... + }; + + template<> + class Placement : public Placement + { }; + + template<> + class Placement : public Placement + { }; diff --git a/src/proc/mobject/session/allocation.cpp b/src/proc/mobject/session/allocation.cpp index e3ed4b701..a590756c3 100644 --- a/src/proc/mobject/session/allocation.cpp +++ b/src/proc/mobject/session/allocation.cpp @@ -1,5 +1,5 @@ /* - Allocation - directive to place a MObject in a specific way + Allocation - objective to place a MObject in a specific way Copyright (C) CinelerraCV 2007, Christian Thaeter diff --git a/src/proc/mobject/session/allocation.hpp b/src/proc/mobject/session/allocation.hpp index 88605572a..5bdd5b88c 100644 --- a/src/proc/mobject/session/allocation.hpp +++ b/src/proc/mobject/session/allocation.hpp @@ -1,5 +1,5 @@ /* - ALLOCATION.hpp - directive to place a MObject in a specific way + ALLOCATION.hpp - objective to place a MObject in a specific way Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -26,7 +26,7 @@ #include -#include "proc/mobject/placement.hpp" +#include "proc/mobject/session/locatingpin.hpp" using std::string; @@ -39,9 +39,10 @@ namespace mobject /** - * a directive to place a MObject in a specific way + * Interface: any objective, constraint or wish of + * placeing a MObject in a specific way. */ - class Allocation : public Placement + class Allocation : public LocatingPin { protected: /** human readable representation of the condition diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index 83696c866..316cbc435 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -25,6 +25,7 @@ #define MOBJECT_SESSION_CLIP_H #include "proc/mobject/session/abstractmo.hpp" +#include "proc/mobject/placement.hpp" @@ -55,6 +56,8 @@ namespace mobject //TODO: where to put the duration ??? }; + + diff --git a/src/proc/mobject/session/fixedplacement.cpp b/src/proc/mobject/session/fixedlocation.cpp similarity index 88% rename from src/proc/mobject/session/fixedplacement.cpp rename to src/proc/mobject/session/fixedlocation.cpp index cfd370501..08c19aa24 100644 --- a/src/proc/mobject/session/fixedplacement.cpp +++ b/src/proc/mobject/session/fixedlocation.cpp @@ -1,5 +1,5 @@ /* - ${Name} - ???????????? needed any longer? + FixedLocation - directly positioning a MObject to a fixed location Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -21,7 +21,7 @@ * *****************************************************/ -#include "proc/mobject/session/fixedplacement.hpp" +#include "proc/mobject/session/fixedlocation.hpp" namespace mobject { diff --git a/src/proc/mobject/session/fixedplacement.hpp b/src/proc/mobject/session/fixedlocation.hpp similarity index 70% rename from src/proc/mobject/session/fixedplacement.hpp rename to src/proc/mobject/session/fixedlocation.hpp index badf3e781..e3a51056b 100644 --- a/src/proc/mobject/session/fixedplacement.hpp +++ b/src/proc/mobject/session/fixedlocation.hpp @@ -1,5 +1,5 @@ /* - FIXEDPLACEMENT.hpp - TODO: didn't we plan to rename ExplicitPlacement to DirectPlacement?? + FIXEDLOCATION.hpp - directly positioning a MObject to a fixed location Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -21,11 +21,10 @@ */ -#ifndef MOBJECT_SESSION_FIXEDPLACEMENT_H -#define MOBJECT_SESSION_FIXEDPLACEMENT_H +#ifndef MOBJECT_SESSION_FIXEDLOCATION_H +#define MOBJECT_SESSION_FIXEDLOCATION_H -#include "proc/mobject/placement.hpp" -#include "proc/mobject/explicitplacement.hpp" +#include "proc/mobject/session/locatingpin.hpp" @@ -34,9 +33,11 @@ namespace mobject namespace session { - // TODO: didn't we plan to rename ExplicitPlacement to DirectPlacement?? - - class DirectPlacement : public ExplicitPlacement + /** + * The most common case of positioning a MObject + * in the EDL: directly specifying a constant position. + */ + class FixedLocation : public LocatingPing { /////////// }; diff --git a/src/proc/mobject/session/chainplacement.cpp b/src/proc/mobject/session/locatingpin.cpp similarity index 89% rename from src/proc/mobject/session/chainplacement.cpp rename to src/proc/mobject/session/locatingpin.cpp index 3c5393ddd..be9b2863c 100644 --- a/src/proc/mobject/session/chainplacement.cpp +++ b/src/proc/mobject/session/locatingpin.cpp @@ -1,5 +1,5 @@ /* - ChainPlacement - Chaining and additionally constraining Placements + LocatingPin - Chaining and constraining the Placement of a Media Object Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -21,7 +21,7 @@ * *****************************************************/ -#include "proc/mobject/session/chainplacement.hpp" +#include "proc/mobject/session/locatingpin.hpp" #include "proc/mobject/placement.hpp" namespace mobject diff --git a/src/proc/mobject/session/chainplacement.hpp b/src/proc/mobject/session/locatingpin.hpp similarity index 79% rename from src/proc/mobject/session/chainplacement.hpp rename to src/proc/mobject/session/locatingpin.hpp index db71b8c1f..ceb39c4c4 100644 --- a/src/proc/mobject/session/chainplacement.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -1,5 +1,5 @@ /* - CHAINPLACEMENT.hpp - Chaining and additionally constraining Placements + LOCATINGPIN.hpp - Chaining and constraining the Placement of a Media Object Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -21,8 +21,8 @@ */ -#ifndef MOBJECT_SESSION_CHAINPLACEMENT_H -#define MOBJECT_SESSION_CHAINPLACEMENT_H +#ifndef MOBJECT_SESSION_LOCATINGPIN_H +#define MOBJECT_SESSION_LOCATINGPIN_H @@ -37,12 +37,11 @@ namespace mobject class RelativePlacement; - template - struct ChainPlacement + struct LocatingPin { protected: - /** next additional Placement, if any */ - Placement * next; + /** next additional Pin, if any */ + LocatingPin * next; public: FixedPlacement& operator() (Time); diff --git a/src/proc/mobject/session/relativeplacement.cpp b/src/proc/mobject/session/relativelocation.cpp similarity index 100% rename from src/proc/mobject/session/relativeplacement.cpp rename to src/proc/mobject/session/relativelocation.cpp diff --git a/src/proc/mobject/session/relativeplacement.hpp b/src/proc/mobject/session/relativelocation.hpp similarity index 84% rename from src/proc/mobject/session/relativeplacement.hpp rename to src/proc/mobject/session/relativelocation.hpp index 1836d689d..577c741f3 100644 --- a/src/proc/mobject/session/relativeplacement.hpp +++ b/src/proc/mobject/session/relativelocation.hpp @@ -1,5 +1,5 @@ /* - RELATIVEPLACEMENT.hpp - Placement implemnetaion providing various ways of attaching a MObject to another one + RELATIVELOCATION.hpp - Placement implementation attaching MObjects relative to another one Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -21,10 +21,10 @@ */ -#ifndef MOBJECT_SESSION_RELATIVEPLACEMENT_H -#define MOBJECT_SESSION_RELATIVEPLACEMENT_H +#ifndef MOBJECT_SESSION_RELATIVELOCATION_H +#define MOBJECT_SESSION_RELATIVELOCATION_H -#include "proc/mobject/placement.hpp" +#include "proc/mobject/session/locatingpin.hpp" @@ -36,7 +36,7 @@ namespace mobject - class RelativePlacement : public Placement + class RelativeLocation : public LocatingPin { public: diff --git a/uml/cinelerra3/128133.diagram b/uml/cinelerra3/128133.diagram index a6da87c99..2df4f1453 100644 --- a/uml/cinelerra3/128133.diagram +++ b/uml/cinelerra3/128133.diagram @@ -22,7 +22,7 @@ classcanvas 129413 class_ref 128517 // MObject end classcanvas 129669 class_ref 128645 // Placement draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 539 121 2000 + xyz 634 120 2000 end classcanvas 129925 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_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 @@ -44,17 +44,17 @@ classcanvas 131973 class_ref 129157 // Meta draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 389 368 2000 end -classcanvas 132229 class_ref 129285 // FixedPlacement +classcanvas 132229 class_ref 129285 // FixedLocation draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 678 374 2005 + xyz 608 332 2005 end -classcanvas 132869 class_ref 129413 // RelativePlacement +classcanvas 132869 class_ref 129413 // RelativeLocation draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 477 342 2000 + xyz 491 332 2000 end classcanvas 134149 class_ref 129541 // Allocation draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 592 342 2000 + xyz 568 427 2000 end classcanvas 134405 class_ref 129669 // Label 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 @@ -62,7 +62,7 @@ classcanvas 134405 class_ref 129669 // Label end classcanvas 135429 class_ref 129797 // ExplicitPlacement draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 673 258 2004 + xyz 715 276 2004 end classcanvas 135813 class_ref 129797 // ExplicitPlacement 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 @@ -80,11 +80,11 @@ textcanvas 137093 "Fixture is the actual assembly of various Media Objects ready xyzwh 39 909 2000 147 108 classcanvas 137221 class_ref 130053 // Wish draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 573 485 2000 + xyz 561 532 2000 end classcanvas 137349 class_ref 130181 // Constraint draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 623 485 2000 + xyz 616 532 2000 end classcanvas 138629 class_ref 135173 // Segment 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 @@ -102,9 +102,9 @@ classcanvas 139653 class_ref 139781 // SessManager draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 101 301 2000 end -classcanvas 141317 class_ref 139909 // ChainPlacement +classcanvas 141317 class_ref 139909 // LocatingPin draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 677 148 2000 + xyz 518 239 2000 end relationcanvas 128389 relation_ref 128005 // from ref 128005 z 1999 to ref 128133 @@ -157,27 +157,19 @@ relationcanvas 132101 relation_ref 129669 // no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 132997 relation_ref 129925 // - from ref 132869 z 1999 to point 529 240 - line 133893 z 1999 to ref 129413 - role_a_pos 413 204 3000 no_role_b - multiplicity_a_pos 401 197 3000 multiplicity_b_pos 515 317 3000 + from ref 132869 z 1999 to point 455 329 + line 133893 z 1999 to point 430 252 + line 144389 z 1999 to ref 129413 + role_a_pos 417 223 3000 no_role_b + multiplicity_a_pos 406 208 3000 multiplicity_b_pos 474 359 3000 relationcanvas 134533 relation_ref 130309 // from ref 134405 z 1999 to ref 131973 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 135173 relation_ref 130565 // - from ref 134149 z 1999 to point 576 266 - line 142853 z 1999 to ref 129669 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 135301 relation_ref 130693 // - from ref 132869 z 1999 to ref 129669 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 135685 relation_ref 130949 // geometry VHV - from ref 135429 z 1999 to point 724 236 - line 141445 z 1999 to point 576 236 + from ref 135429 z 1999 to point 766 245 + line 141445 z 1999 to point 671 245 line 141573 z 1999 to ref 129669 no_role_a no_role_b no_multiplicity_a no_multiplicity_b @@ -226,20 +218,37 @@ relationcanvas 139781 relation_ref 142853 // multiplicity_a_pos 126 426 3000 no_multiplicity_b relationcanvas 140165 relation_ref 142981 // from ref 129669 z 1999 to ref 129413 - role_a_pos 401 145 3000 no_role_b - multiplicity_a_pos 401 178 3000 multiplicity_b_pos 512 178 3000 -relationcanvas 140293 relation_ref 143109 // - from ref 132229 z 1999 to ref 135429 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b + role_a_pos 413 151 3000 no_role_b + multiplicity_a_pos 403 151 3000 multiplicity_b_pos 589 153 3000 relationcanvas 142213 relation_ref 143237 // from ref 129669 z 1999 to ref 141317 - role_a_pos 640 145 3000 no_role_b - multiplicity_a_pos 664 171 3000 no_multiplicity_b -relationcanvas 142341 relation_ref 143365 // - from ref 141317 z 1999 to point 724 207 - line 142597 z 1999 to point 637 207 - line 142725 z 1999 to ref 129669 - role_a_pos 640 191 3000 no_role_b + role_a_pos 578 200 3000 no_role_b + multiplicity_a_pos 599 233 3000 no_multiplicity_b +relationcanvas 142981 relation_ref 143493 // + geometry VHV + from ref 132869 z 1999 to point 539 304 + line 143493 z 1999 to point 554 304 + line 143621 z 1999 to ref 141317 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 143109 relation_ref 143621 // + geometry VHV + from ref 132229 z 1999 to point 650 304 + line 143749 z 1999 to point 554 304 + line 143877 z 1999 to ref 141317 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 143237 relation_ref 143749 // + geometry VHV unfixed + from ref 134149 z 1999 to point 599 304 + line 144005 z 1999 to point 554 304 + line 144133 z 1999 to ref 141317 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 144517 relation_ref 143877 // + from ref 141317 z 1999 to point 488 239 + line 144645 z 1999 to point 488 269 + line 144773 z 1999 to ref 141317 + role_a_pos 492 244 3000 no_role_b no_multiplicity_a no_multiplicity_b end diff --git a/uml/cinelerra3/128261 b/uml/cinelerra3/128261 index de4cec32a..9925728b7 100644 --- a/uml/cinelerra3/128261 +++ b/uml/cinelerra3/128261 @@ -1,6 +1,6 @@ format 40 "MObject" // ProcessingLayer::MObject - revision 24 + revision 26 modified_by 5 "hiv" // class settings //class diagram settings @@ -485,7 +485,7 @@ ${class}::${name} ${(}const ${t0}& ${p0}${)}${const}${volatile} ${throw}${static cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; " classrelation_ref 145413 // chain () - b multiplicity "" parent class_ref 139909 // ChainPlacement + b multiplicity "" parent class_ref 139909 // LocatingPin end end @@ -701,7 +701,7 @@ ${inlines} end end - class 129285 "FixedPlacement" + class 129285 "FixedLocation" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -712,16 +712,16 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 145285 // - relation 143109 ---|> + classrelation 145797 // + relation 143621 ---|> a public cpp default "${type}" - classrelation_ref 145285 // - b multiplicity "" parent class_ref 129797 // ExplicitPlacement + classrelation_ref 145797 // + b multiplicity "" parent class_ref 139909 // LocatingPin end end - class 129413 "RelativePlacement" + class 129413 "RelativeLocation" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -751,14 +751,6 @@ ${inlines} comment "the kind of relation denoted by this Placement" end - classrelation 131333 // - relation 130693 ---|> - a public - cpp default "${type}" - classrelation_ref 131333 // - b multiplicity "" parent class_ref 128645 // Placement - end - attribute 129029 "offset" protected type class_ref 134917 // Time init_value "0" @@ -802,6 +794,14 @@ ${items}}; comment "attach subject to anchor (e.g. an effect to a clip)" end end + + classrelation 145669 // + relation 143493 ---|> + a public + cpp default "${type}" + classrelation_ref 145669 // + b multiplicity "" parent class_ref 139909 // LocatingPin + end end class 129541 "Allocation" @@ -816,14 +816,6 @@ ${inlines} explicit_switch_type "" comment "a directive to place a MObject in a specific way" - classrelation 131205 // - relation 130565 ---|> - a public - cpp default "${type}" - classrelation_ref 131205 // - b multiplicity "" parent class_ref 128645 // Placement - end - attribute 128773 "repr" protected explicit_type "string" cpp_decl " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; @@ -851,6 +843,14 @@ ${inlines} idl_name_spec "get_${name}" get_of_attribute attribute_ref 128773 // repr end + + classrelation 145925 // + relation 143749 ---|> + a public + cpp default "${type}" + classrelation_ref 145925 // + b multiplicity "" parent class_ref 139909 // LocatingPin + end end class 129669 "Label" @@ -1080,7 +1080,7 @@ ${inlines} comment "Provides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter" end - class 139909 "ChainPlacement" + class 139909 "LocatingPin" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -1091,14 +1091,15 @@ ${inlines} idl_decl "" explicit_switch_type "" - classrelation 145541 // next () - relation 143365 ---> + comment "An element with value semantics, which actually implements the placement of some MObject by positioning it in some way." + classrelation 146053 // next () + relation 143877 ---> a role_name "next" multiplicity "" protected - comment "next additional Placement, if any" + comment "next additional LocatingPin, if any" cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; " - classrelation_ref 145541 // next () - b multiplicity "" parent class_ref 128645 // Placement + classrelation_ref 146053 // next () + b multiplicity "" parent class_ref 139909 // LocatingPin end end end diff --git a/uml/cinelerra3/129285 b/uml/cinelerra3/129285 index 1c121e419..ec9e7d7fc 100644 --- a/uml/cinelerra3/129285 +++ b/uml/cinelerra3/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 4 + revision 5 modified_by 5 "hiv" // class settings //class diagram settings @@ -226,7 +226,7 @@ format 40 end classinstance 130053 "" - type class_ref 129413 // RelativePlacement + type class_ref 129413 // RelativeLocation attributes attribute_ref 128133 // relType "SAMETIME" @@ -250,7 +250,7 @@ format 40 end classinstance 130309 "" - type class_ref 129413 // RelativePlacement + type class_ref 129413 // RelativeLocation attributes attribute_ref 129029 // offset "+3" diff --git a/uml/cinelerra3/130437 b/uml/cinelerra3/130437 index df17fa821..b1c2021e8 100644 --- a/uml/cinelerra3/130437 +++ b/uml/cinelerra3/130437 @@ -1,6 +1,6 @@ format 40 "session" // design::codegen::proc::mobject::session - revision 10 + revision 11 modified_by 5 "hiv" // class settings //class diagram settings @@ -511,7 +511,7 @@ ${namespace_end}" comment "abstract base class of all MObjects representing meta data or processing instructions" end - artifact 139013 "chainplacement" + artifact 139013 "locatingpin" stereotype "source" cpp_h "/* ${NAME}.hpp - ${description} @@ -545,12 +545,12 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 139909 // ChainPlacement + class_ref 139909 // LocatingPin end - comment "Chaining and additionally constraining Placements" + comment "Chaining and constraining the Placement of a Media Object" end - artifact 129797 "fixedplacement" + artifact 129797 "fixedlocation" stereotype "source" cpp_h "/* ${NAME}.hpp - ${description} @@ -584,11 +584,12 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 129285 // FixedPlacement + class_ref 129285 // FixedLocation end + comment "implements fixed placement of a MObject" end - artifact 129925 "relativeplacement" + artifact 129925 "relativelocation" stereotype "source" cpp_h "/* ${NAME}.hpp - ${description} @@ -622,7 +623,7 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 129413 // RelativePlacement + class_ref 129413 // RelativeLocation end comment "Placement implemnetaion providing various ways of attaching a MObject to another one" end diff --git a/uml/cinelerra3/5.session b/uml/cinelerra3/5.session index 49af64898..9440f200a 100644 --- a/uml/cinelerra3/5.session +++ b/uml/cinelerra3/5.session @@ -4,21 +4,17 @@ diagrams 860 633 100 4 0 0 active classdiagram_ref 128133 // Session structure 860 633 100 4 0 0 - classdiagram_ref 130437 // Media-Asset Relations - 860 633 100 4 0 0 classdiagram_ref 128389 // Render Entities 688 506 100 4 120 0 end show_stereotypes -selected class_ref 129285 // FixedPlacement +selected + package_ref 129 // cinelerra3 open - deploymentview_ref 128133 // EXE Deployment - deploymentview_ref 128773 // gen - deploymentview_ref 128901 // gen - classview_ref 128901 // Assets - class_ref 128517 // MObject class_ref 128645 // Placement - class_ref 129413 // RelativePlacement + class_ref 129413 // RelativeLocation + class_ref 129541 // Allocation + class_ref 139909 // LocatingPin classview_ref 129029 // Interface usecaseview_ref 128133 // usage end diff --git a/uml/cinelerra3/cinelerra3.prj b/uml/cinelerra3/cinelerra3.prj index efde6fe95..62217077f 100644 --- a/uml/cinelerra3/cinelerra3.prj +++ b/uml/cinelerra3/cinelerra3.prj @@ -1,6 +1,6 @@ format 40 "cinelerra3" - revision 33 + revision 35 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index eefa14ca2..2aaac1a79 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -1359,6 +1359,12 @@ From experiences with other middle scale projects, I prefer having the test code {{red{how to create a test stub for this interface...?}}} +
          +
          Used to actually implement the various kinds of [[Placement]] of ~MObjects. ~LocationPin is the root of a hierarchy of different kinds of placing, constraining and locating a Media Object. Basically, this is an instance of the ''state pattern'': The user sees one Placement object with value semantics, but when the properties of the Placement are changed, actually a ~LocationPin object (or rather a chain of ~LocationPins) is changed within the Placement. Subclasses of ~LocationPin implement different placing/constraining behaviour:
          +* {{{FixedLocation}}} places a MObject to a fixed temporal position and track
          +* {{{RelativeLocation}}} is used to atach the MObject to some other anchor MObject
          +* //additional constraints, placement objectives, range restrictions, pattern rules will follow...//
          +
          All sorts of "things" to be placed and manipulated by the user in the EDL. This interface abstracts the details and just supposes
           * the media object has a duration
          @@ -2079,19 +2085,20 @@ DAMAGE.
           
           The fact of being placed in the [[Session|SessionOverview]]/[[EDL]]is constitutive for all sorts of [[MObject]]s, without Placement they make no sense. Thus &mdash; technically &mdash; Placements act as ''smart pointers''. Of course, there are several kinds of Placements and they are templated on the type of MObject they are refering to. Placements can be //aggregated// to increasingly constrain the resulting "location" of the refered ~MObject. See &rarr; [[handling of Placements|PlacementHandling]] for more details
          -
          -
          [[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length).
          +
          +
          [[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length). Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object.
           
          -Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object. Each Placement has a ''kind'', which determines its actual placing and locating behaviour, but besides that, we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement of some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour.
          +Actually, the way each Placement locates its subject is implemented by one or several small LocationPin objects, where subclasses of LocationPin implement the various differend methods of placing and resolving the final location. Notably, we can give a ~FixedLocation or we can atach to another ~MObject to get a ~RelativeLocation, etc.
           
          -There is no limitation to one single Placement per ~MObject, indeed we can ''aggregate'' several Placements, resulting in their properties and constraints being combined to yield the actual position of the ~MObject refered by those Placements. 
          +Placements have //value semantics,// i.e. we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement parametrized to some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour. There is no limitation to one single Placement per ~MObject, indeed we have several different Placements of the same MObject (from a users point of view, this behaves like having clones). Besides, we can ''aggregate'' additional [[LocationPin]]a to one Placements, resulting in their properties and constraints being combined to yield the actual position of the referred ~MObject.
           
           !design decisions
          -* Placements can be aggregated in a sort of chain.
          +* the actual way of placing is implemented similar to the ''State Pattern'' by small embedded LoctionPin objects.
          +* these LocationPin objects form a ''decorator'' like chain
           * resolving into an ExplicitPlacement traverses this chain
          -* //overconstraining// a placement is not an error, we just stop traversing the chain (ignoring the remaining additionla Placements) at the moment the position is completely defined. 
          -* {{red{question...}}} how to implement this? externally, decorator-style or using the State pattern?
          -* {{red{problem...}}} how to get at the individual MObject sub-Interfaces. Why is this a Problem?
          +* //overconstraining// a placement is not an error, we just stop traversing the chain (ignoring the remaining additional Placements) at the moment the position is completely defined. 
          +* we provide subclasses to be able to form collections of e.g. {{{Placement<Effect>}}}, but we don't stress polymorphism here. Instead we stick to value semantics and explicitly ''allow slicing'' (all subclasses have the same size and layout and differ only in their vtable contents). This is justified, because for the polymorphical treating of ~MObjects the visitor mechanism used by the builder and the EDL is sufficiant, and I don't want to add another layer of complexity by making Placement something like {{{boost::variant}}}.
          +* Why is the question how to access a ~MObject subinterface a Problem?
           *# we want the EDL/Fixture to be a collection of Placements. This means, either we store pointers, or Placement needs to be //one// unique type!
           *# but if Placement is //a single type//, then we can get only MObjects from a Placement.
           *# then either we had to do everything by a visitor (which gets the concrete subtype dynamically), or we'd end up switching on type.
          
          From be49b799a2397bee4cf5cf7c86bf1bfd366f1ade Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Thu, 18 Oct 2007 17:35:06 +0200
          Subject: [PATCH 05/22] typo
          
          ---
           wiki/renderengine.html | 14 +++++++-------
           1 file changed, 7 insertions(+), 7 deletions(-)
          
          diff --git a/wiki/renderengine.html b/wiki/renderengine.html
          index 2aaac1a79..d09474bec 100644
          --- a/wiki/renderengine.html
          +++ b/wiki/renderengine.html
          @@ -1359,8 +1359,8 @@ From experiences with other middle scale projects, I prefer having the test code
           
           {{red{how to create a test stub for this interface...?}}}
          -
          -
          Used to actually implement the various kinds of [[Placement]] of ~MObjects. ~LocationPin is the root of a hierarchy of different kinds of placing, constraining and locating a Media Object. Basically, this is an instance of the ''state pattern'': The user sees one Placement object with value semantics, but when the properties of the Placement are changed, actually a ~LocationPin object (or rather a chain of ~LocationPins) is changed within the Placement. Subclasses of ~LocationPin implement different placing/constraining behaviour:
          +
          +
          Used to actually implement the various kinds of [[Placement]] of ~MObjects. ~LocatingPin is the root of a hierarchy of different kinds of placing, constraining and locating a Media Object. Basically, this is an instance of the ''state pattern'': The user sees one Placement object with value semantics, but when the properties of the Placement are changed, actually a ~LocatingPin object (or rather a chain of ~LocatingPins) is changed within the Placement. Subclasses of ~LocatingPin implement different placing/constraining behaviour:
           * {{{FixedLocation}}} places a MObject to a fixed temporal position and track
           * {{{RelativeLocation}}} is used to atach the MObject to some other anchor MObject
           * //additional constraints, placement objectives, range restrictions, pattern rules will follow...//
          @@ -2085,16 +2085,16 @@ DAMAGE. The fact of being placed in the [[Session|SessionOverview]]/[[EDL]]is constitutive for all sorts of [[MObject]]s, without Placement they make no sense. Thus &mdash; technically &mdash; Placements act as ''smart pointers''. Of course, there are several kinds of Placements and they are templated on the type of MObject they are refering to. Placements can be //aggregated// to increasingly constrain the resulting "location" of the refered ~MObject. See &rarr; [[handling of Placements|PlacementHandling]] for more details
          -
          +
          [[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length). Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object.
           
          -Actually, the way each Placement locates its subject is implemented by one or several small LocationPin objects, where subclasses of LocationPin implement the various differend methods of placing and resolving the final location. Notably, we can give a ~FixedLocation or we can atach to another ~MObject to get a ~RelativeLocation, etc.
          +Actually, the way each Placement locates its subject is implemented by one or several small LocatingPin objects, where subclasses of LocatingPin implement the various differend methods of placing and resolving the final location. Notably, we can give a ~FixedLocation or we can atach to another ~MObject to get a ~RelativeLocation, etc.
           
          -Placements have //value semantics,// i.e. we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement parametrized to some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour. There is no limitation to one single Placement per ~MObject, indeed we have several different Placements of the same MObject (from a users point of view, this behaves like having clones). Besides, we can ''aggregate'' additional [[LocationPin]]a to one Placements, resulting in their properties and constraints being combined to yield the actual position of the referred ~MObject.
          +Placements have //value semantics,// i.e. we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement parametrized to some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour. There is no limitation to one single Placement per ~MObject, indeed we have several different Placements of the same MObject (from a users point of view, this behaves like having clones). Besides, we can ''aggregate'' additional [[LocatingPin]]a to one Placements, resulting in their properties and constraints being combined to yield the actual position of the referred ~MObject.
           
           !design decisions
          -* the actual way of placing is implemented similar to the ''State Pattern'' by small embedded LoctionPin objects.
          -* these LocationPin objects form a ''decorator'' like chain
          +* the actual way of placing is implemented similar to the ''State Pattern'' by small embedded LocatingPin objects.
          +* these LocatingPin objects form a ''decorator'' like chain
           * resolving into an ExplicitPlacement traverses this chain
           * //overconstraining// a placement is not an error, we just stop traversing the chain (ignoring the remaining additional Placements) at the moment the position is completely defined. 
           * we provide subclasses to be able to form collections of e.g. {{{Placement<Effect>}}}, but we don't stress polymorphism here. Instead we stick to value semantics and explicitly ''allow slicing'' (all subclasses have the same size and layout and differ only in their vtable contents). This is justified, because for the polymorphical treating of ~MObjects the visitor mechanism used by the builder and the EDL is sufficiant, and I don't want to add another layer of complexity by making Placement something like {{{boost::variant}}}.
          
          From d7e7d3d613160de3baeadcd292c61c28a1e2dcf9 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Fri, 19 Oct 2007 06:39:52 +0200
          Subject: [PATCH 06/22] WIP implementing Placement and MObject factory
           functions
          
          ---
           src/common/util.hpp                           |   6 +-
           src/proc/mobject/explicitplacement.hpp        |  39 ++++--
           src/proc/mobject/mobject.hpp                  |  12 +-
           src/proc/mobject/placement.cpp                |  57 ---------
           src/proc/mobject/placement.hpp                | 120 ++++++++++++++----
           src/proc/mobject/session/abstractmo.hpp       |  10 +-
           src/proc/mobject/session/locatingpin.hpp      |  23 +++-
           src/proc/mobject/session/mobjectfactory.cpp   |  64 ++++++++++
           .../mobjectfactory.hpp}                       |  37 +++++-
           9 files changed, 265 insertions(+), 103 deletions(-)
           delete mode 100644 src/proc/mobject/placement.cpp
           create mode 100644 src/proc/mobject/session/mobjectfactory.cpp
           rename src/proc/mobject/{explicitplacement.cpp => session/mobjectfactory.hpp} (59%)
          
          diff --git a/src/common/util.hpp b/src/common/util.hpp
          index 3d74d4ed8..9780fe65e 100644
          --- a/src/common/util.hpp
          +++ b/src/common/util.hpp
          @@ -149,7 +149,9 @@ namespace util
             
           } // namespace util
           
          - /* some common macro definitions */
          +
          +
          + /* === some common macro definitions === */
           
           /** supress "warning: unused variable" on vars, which
            *  are introduced into a scope because of some sideeffect, i.e. Locking
          @@ -160,5 +162,7 @@ namespace util
           #define STRINGIFY(TOKEN) __STRNGFY(TOKEN)
           #define __STRNGFY(TOKEN) #TOKEN
           
          +/** shortcut for subclass test, intended for assertions */
          +#define INSTANCEOF(CLASS, EXPR) (dynamic_cast (EXPR)) 
           
           #endif /*UTIL_HPP_*/
          diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp
          index 00e77812b..1e4f5beca 100644
          --- a/src/proc/mobject/explicitplacement.hpp
          +++ b/src/proc/mobject/explicitplacement.hpp
          @@ -1,5 +1,5 @@
           /*
          -  EXPLICITPLACEMENT.hpp  -  special Placement yielding an absolute location (Time,Track)-location for a MObject
          +  EXPLICITPLACEMENT.hpp  -  special Placement yielding an absolute location (Time,Track) for a MObject
            
             Copyright (C)         CinelerraCV
               2007,               Christian Thaeter 
          @@ -31,18 +31,41 @@
           namespace mobject
             {
           
          -  namespace session{ class Track; }
           
           
          -  // TODO: need Garbage Collector for this class!!!!!
          -
          -  class ExplicitPlacement : public Placement
          +  /**
          +   * Special kind of Placement, where the location of the
          +   * MObject has been nailed down to a fixed position.
          +   * The Session allways contains one special EDL, which
          +   * actually is a snapshot of all EDLs contents fixed
          +   * and reduced to simple positions. This so called Fixture
          +   * contains only ExplicitPlacement objects and is processed
          +   * by the Builder to create the render engine  node network.
          +   *
          +   * @see Placement#resolve factory method for deriving an ExplicitPlacement 
          +   */
          +  class ExplicitPlacement : public Placement
               {
          -    protected:
          +    public:
          +      const Time time;
          +      const Track track;
           
          -      Time time;
          -      Track* track;
          +      /** no need to resolve any further, as this ExplicitPlacement
          +       *  already \i is the result of a resolve()-call.
          +       */
          +      virtual const 
          +      ExplicitPlacement resolve ()  const 
          +        { 
          +          return *this; 
          +        }
           
          +    private:
          +      ExplicitPlacement (Placement& base, Time ti, Track tra)
          +        : Placement(base),
          +          time(ti), track(tra)
          +        { };
          +        
          +      friend class session::LocatingPin;
               };
           
           
          diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp
          index b670d1e47..347d8e5a1 100644
          --- a/src/proc/mobject/mobject.hpp
          +++ b/src/proc/mobject/mobject.hpp
          @@ -29,6 +29,7 @@
           
           #include "cinelerra.h"
           #include "proc/mobject/buildable.hpp"
          +#include "proc/mobject/placement.hpp"
           #include "proc/asset.hpp"                 // TODO finally not needed?
           
           
          @@ -43,7 +44,10 @@ using proc_interface::AssetManager;
           namespace mobject
             {
           
          -  class Placement;
          +  namespace session
          +    {
          +    class MObjectFactory;
          +    }
           
           
             /**
          @@ -63,14 +67,16 @@ namespace mobject
                 virtual ~MObject() {};
                 
               public:
          -      virtual shared_ptr& getPlacement () =0;
          +      static session::MObjectFactory create;
          +      
                 virtual PAsset getMedia () =0; ///< @todo solve the reference/Interface problem concerning Placements, then push down
                 virtual Time& getLength() =0; ///< @todo how to deal with the time/length field??
           
               };
             
             
          -  typedef shared_ptr PMO;
          +  typedef Placement PMO;
          +  
           
           
           
          diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp
          deleted file mode 100644
          index 27a7b1e4d..000000000
          --- a/src/proc/mobject/placement.cpp
          +++ /dev/null
          @@ -1,57 +0,0 @@
          -/*
          -  Placement  -  Key Abstraction: a way to place and locate a Media Object
          - 
          -  Copyright (C)         CinelerraCV
          -    2007,               Christian Thaeter 
          - 
          -  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/placement.hpp"
          -#include "proc/mobject/explicitplacement.hpp"
          -
          -namespace mobject
          -  {
          -
          -
          -  /** factory for creating the corretct Placement subclass */
          -  PlacementFactory Placement::create;
          -
          -
          -  /** create an actual (explicit) placement while trying to
          -   * satisfy the network of adjacent objects and placements.
          -   */
          -  ExplicitPlacement
          -  Placement::resolve ()
          -  {
          -  }
          -  
          -  
          -  
          -  /** implements the logic for selecting the correct 
          -   *  Placement subclass.
          -   *  @return smart ptr owning the created placement object
          -   */
          -  PlacementFactory::PType 
          -  PlacementFactory::operator() (Placement::Style, Time, PMO subject)
          -  {
          -    UNIMPLEMENTED ("create correct Placement subclass");
          -  }
          -
          -
          -
          -} // namespace mobject
          diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp
          index 4c0504594..4d8a2ac4c 100644
          --- a/src/proc/mobject/placement.hpp
          +++ b/src/proc/mobject/placement.hpp
          @@ -23,22 +23,32 @@
           
           /** @file placement.hpp 
            ** Placements are at the very core of all editing operations,
          - ** because they act as handles (smart pointers) to access the media objects
          - ** to be manipulated. Moreover, Placements are the actual content of the EDL(s)
          - ** and Fixture and thus are small objects with value semantics. Many editing tasks
          - ** include finding some Placement in the EDL or directly take a ref to some Placement.
          + ** because they act as handles to access the media objects to be manipulated. 
          + ** Moreover, Placements are the actual content of the EDL(s) and Fixture and thus
          + ** are small objects with value semantics. Many editing tasks include locating some
          + ** Placement in the EDL or directly take a ref to a Placement.
            ** 
          - ** Placements are smart pointers: By acting on the Placement object, we can change
          - ** parameters of the way the media object is placed (e.g. adjust an offset), while by 
          - ** dereferencing the Placement object, we access the "real" media object (e.g. for trimming).
          + ** Placements are refcounting smart pointers: By acting on the Placement object,
          + ** we can change parameters of the way the media object is placed (e.g. adjust an offset), 
          + ** while by dereferencing the Placement object, we access the "real" media object.
          + ** Usually, any MObject is created by a factory and immediately wrapped into a Placement,
          + ** which takes ownership of the MObject.
          + **
          + ** Besides being a handle, Placements define the logical position where some MObject is
          + ** supposed to be located within the EDL or Fixture. The way in which this placing happens
          + ** is controlled and parametrized by a collection (chain) of LocatingPin objects. By adding
          + ** to this chain, the position of the MObject is increasingly constrained. The simplest
          + ** case of such constraining is to add a FixedLocation, thus placing the MObject at one
          + ** absolute position (time, track).
            ** 
            ** Placements are templated on the type of the actual MObject they refer to, so, sometimes
            ** we rather use a Placement to be able to use the more specific methods of the
            ** session::Clip interface. But please note the following detail: this type
          - ** labeling is the only difference between this subclasses, besides that,
          - ** they can be replaced by one another (no slicing).
          + ** labeling and downcasting is the only difference between these subclasses, 
          + ** besides that, they can be replaced literally by one another (slicing is accepted).
            **
            ** @see ExplicitPlacement
          + ** @see LocatingPin interface for controlling the positioning parameters
            **
            */
           
          @@ -47,39 +57,63 @@
           #ifndef MOBJECT_PLACEMENT_H
           #define MOBJECT_PLACEMENT_H
           
          -#include "common/time.hpp"
          -#include "common/factory.hpp"
          -#include "proc/mobject/mobject.hpp"
          +#include "cinelerra.h"
          +#include "proc/mobject/session/abstractmo.hpp"
           #include "proc/mobject/session/locatingpin.hpp"
           #include "proc/mobject/session/track.hpp"
           
          +#include 
          +using std::tr1::shared_ptr;
          +
           
           namespace mobject
             {
           
          -
          +  class MObject;
             class ExplicitPlacement;
           
          +  
           
             template
          -  class Placement : public shared_ptr
          +  class Placement : protected shared_ptr
               {
               protected:
                 typedef cinelerra::Time Time;
          -      typedef session::Track Track;
          +      typedef session::Track* Track;
           
           
               public:
          -      LocatingPin chain;
          +      /** smart pointer: accessing the MObject, 
          +       *  which is subject to placement.
          +       *  @note we don't provide operator*
          +       */
          +      virtual MO * 
          +      operator-> ()  const 
          +        { 
          +          return shared_ptr::operator-> (); 
          +        }      
                 
          -      /** resolve the network of placement and
          +      /** interface for defining the kind of placement
          +       *  to employ, and for controling any additional
          +       *  constraints and properties. 
          +       */
          +      session::LocatingPin chain;
          +      
          +      /** combine and resolve all constraints defined
          +       *  by the various LocatingPin (\see #chain) and
                  *  provide the resulting (explicit) placement.
                  */
          -      virtual ExplicitPlacement resolve () ;
          +      virtual const ExplicitPlacement 
          +      resolve ()  const 
          +        { 
          +          return chain.resolve(); 
          +        }
          +      
                 
               protected:
          -      Placement ();
                 virtual ~Placement() {};
          +      Placement (MO & subject) 
          +        : shared_ptr (&subject, &session::AbstractMO::destroy) {};
               };
             
           
          @@ -92,20 +126,62 @@ namespace mobject
               class Meta;
               }
             
          +  
             template<>
             class Placement : public Placement
               { 
          -      //TODO: overwirte shared_ptr's operator-> to return the correct subtype of MObject...
          +      Placement (session::Clip & c) 
          +        : Placement::Placement (c) 
          +        { };
          +        
          +    public:
          +      virtual session::Clip*
          +      operator-> ()  const 
          +        { 
          +          ENSURE (INSTANCEOF(session::Clip, this.get()));
          +          return static_cast (shared_ptr::operator-> ()); 
          +        }      
               };
             
          +  
             template<>
             class Placement : public Placement
          -    { };
          +    { 
          +      Placement (session::Effect & e) 
          +        : Placement::Placement (e) 
          +        { };
          +        
          +    public:
          +      virtual session::Effect*
          +      operator-> ()  const 
          +        { 
          +          ENSURE (INSTANCEOF(session::Effect, this.get()));
          +          return static_cast (shared_ptr::operator-> ()); 
          +        }      
          +    };
          +  
             
             template<>
             class Placement : public Placement
          -    { };
          +    { 
          +      Placement (session::Meta & m) 
          +        : Placement::Placement (m) 
          +        { };
          +        
          +    public:
          +      virtual session::Meta*
          +      operator-> ()  const 
          +        { 
          +          ENSURE (INSTANCEOF(session::Meta, this.get()));
          +          return static_cast (shared_ptr::operator-> ()); 
          +        }      
          +    };
             
          +  /* a note to the maintainer: please don't add any fields or methods to
          +   * these subclasses which aren't also present in Placement!
          +   * Placements are frequently treated like values and thus slicing
          +   * will happen, which in this special case is acceptable.
          +   */
             
           
           
          diff --git a/src/proc/mobject/session/abstractmo.hpp b/src/proc/mobject/session/abstractmo.hpp
          index 3ea6da648..e0c1867d2 100644
          --- a/src/proc/mobject/session/abstractmo.hpp
          +++ b/src/proc/mobject/session/abstractmo.hpp
          @@ -48,7 +48,15 @@ namespace mobject
                     { 
                       UNIMPLEMENTED ("how to relate MObjects and media assets...");
                       return AssetManager::instance().getAsset(IDA(0)); // KABOOM! (just to make it compile)
          -          }  
          +          }
          +      protected:
          +        /** custom deleter func allowing class Placement 
          +          *  to take ownership of MObjct instances
          +          */
          +        static void destroy (MObject* o) { delete o; }
          +        
          +        friend class Placement;
          +
                };
           
           
          diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp
          index ceb39c4c4..9d372111d 100644
          --- a/src/proc/mobject/session/locatingpin.hpp
          +++ b/src/proc/mobject/session/locatingpin.hpp
          @@ -25,6 +25,11 @@
           #define MOBJECT_SESSION_LOCATINGPIN_H
           
           
          +#include "cinelerra.h"
          +
          +#include 
          +using boost::scoped_ptr;
          +
           
           
           namespace mobject
          @@ -33,18 +38,24 @@ namespace mobject
           
             namespace session
               {
          -      class FixedPlacement;
          -      class RelativePlacement;
          -      
          -
          +    class FixedLocation;
          +    class RelativeLocation;
          +    
          +    
               struct LocatingPin
                 {
                 protected:
          +      typedef cinelerra::Time Time;
          +      typedef session::Track* Track;
          +      
                   /** next additional Pin, if any */
          -        LocatingPin * next;
          +        scoped_ptr next;
                 public:
                   
          -        FixedPlacement& operator() (Time);
          +        /* Factory functions for adding LocationPins */
          +        
          +        FixedLocation&    operator() (Time, Track);
          +        RelativeLocation& operator() (PMO refObj, Time offset=0);
           
                 };
           
          diff --git a/src/proc/mobject/session/mobjectfactory.cpp b/src/proc/mobject/session/mobjectfactory.cpp
          new file mode 100644
          index 000000000..553dc54c5
          --- /dev/null
          +++ b/src/proc/mobject/session/mobjectfactory.cpp
          @@ -0,0 +1,64 @@
          +/*
          +  MObjectFactory  -  creating concrete MObject subclass instances
          + 
          +  Copyright (C)         CinelerraCV
          +    2007,               Christian Thaeter 
          + 
          +  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/mobjectfactory.hpp"
          +#include "proc/mobject/session/clip.hpp"
          +#include "proc/mobject/session/effect.hpp"
          +#include "proc/asset/clip.hpp"
          +#include "proc/asset/effect.hpp"
          +
          +namespace mobject
          +  {
          +  namespace session
          +    {
          +
          +    /** creating a Clip-MObject to be placed within
          +     *  the EDL, based on a clip asset, which typically
          +     *  is obtained by calling the createClip()-function
          +     *  on some asset::Media. The newly created Clip-MO is
          +     *  internally linked with this media Asset and wrapped
          +     *  into a Placement, which takes ownership. So, when the
          +     *  render engine gets across this Clip-MO, it is able to
          +     *  obtain the media information contained in the corresponding
          +     *  asset.
          +     */
          +    Placement   
          +    MObjectFactory::operator() (shared_ptr& mediaDef)
          +    {
          +      //TODO sholdin't we rather store a ref to the underlying media assset??
          +      return Placement (new Clip (mediaDef));
          +    }
          +    
          +    
          +    /** */
          +    Placement
          +    MObjectFactory::operator() (asset::Effect processorDef)
          +    {
          +      
          +    }
          +
          +
          +
          +  } // namespace mobject::session
          +
          +} // namespace mobject
          diff --git a/src/proc/mobject/explicitplacement.cpp b/src/proc/mobject/session/mobjectfactory.hpp
          similarity index 59%
          rename from src/proc/mobject/explicitplacement.cpp
          rename to src/proc/mobject/session/mobjectfactory.hpp
          index a81777501..9ec54c4ba 100644
          --- a/src/proc/mobject/explicitplacement.cpp
          +++ b/src/proc/mobject/session/mobjectfactory.hpp
          @@ -1,5 +1,5 @@
           /*
          -  ExplicitPlacement  -  special Placement yielding an absolute location (Time,Track)-location for a MObject
          +  MOBJECTFACTORY.hpp  -  creating concrete MObject subclass instances
            
             Copyright (C)         CinelerraCV
               2007,               Christian Thaeter 
          @@ -18,16 +18,43 @@
             along with this program; if not, write to the Free Software
             Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
            
          -* *****************************************************/
          +*/
           
           
          -#include "proc/mobject/explicitplacement.hpp"
          +#ifndef MOBJECT_SESSION_MOBJECTFACTORY_H
          +#define MOBJECT_SESSION_MOBJECTFACTORY_H
          +
          +#include "proc/mobject/mobject.hpp"
          +
          +
          +
          +namespace asset
          +  {
          +  class Clip;
          +  class Effect;
          +  }
           
           namespace mobject
             {
          -
          -  /** */
          +  namespace session
          +    {
          +    class Clip;
          +    class Effect;
           
           
          +    class MObjectFactory
          +      {
          +      public:
          +        typedef Placement PType;
          +        
          +        PType   operator() (const asset::Clip);
          +        PType operator() (const asset::Effect);
          +        
          +      };
          +
          +
          +
          +  } // namespace mobject::session
           
           } // namespace mobject
          +#endif
          
          From dee1bab28bc051362c1a015c7ebafbcb2e8ef81f Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Fri, 19 Oct 2007 22:34:07 +0200
          Subject: [PATCH 07/22] WIP implement the missing create-Clip-from-Asset
           mechanics
          
          ---
           src/proc/asset.cpp                          |  5 +-
           src/proc/asset.hpp                          |  2 +-
           src/proc/asset/clip.cpp                     | 39 +++++++++++-
           src/proc/asset/clip.hpp                     | 18 +++++-
           src/proc/asset/media.cpp                    | 67 ++++++++++++++++++---
           src/proc/asset/media.hpp                    | 41 ++++++++++++-
           src/proc/assetmanager.cpp                   |  2 +-
           src/proc/assetmanager.hpp                   |  2 +-
           src/proc/mobject/mobject.cpp                |  5 +-
           src/proc/mobject/mobject.hpp                |  3 +
           src/proc/mobject/placement.hpp              |  2 +
           src/proc/mobject/session/abstractmo.hpp     |  2 +-
           src/proc/mobject/session/clip.cpp           | 21 ++++++-
           src/proc/mobject/session/clip.hpp           |  8 +++
           src/proc/mobject/session/mobjectfactory.cpp |  2 +-
           src/proc/mobject/session/mobjectfactory.hpp |  4 +-
           wiki/renderengine.html                      | 33 ++++++++--
           17 files changed, 226 insertions(+), 30 deletions(-)
          
          diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp
          index 8780ca518..4fb8429a8 100644
          --- a/src/proc/asset.cpp
          +++ b/src/proc/asset.cpp
          @@ -46,8 +46,9 @@ namespace asset
              */
             Asset::Asset (const Ident& idi) 
               : ident(idi), id(AssetManager::reg (this, idi)) 
          -  {     TRACE (assetmem, "ctor Asset(id=%lu) :  adr=%x %s", size_t(id), this, cStr(this->ident) );
          -}
          +  {
          +    TRACE (assetmem, "ctor Asset(id=%lu) :  adr=%x %s", size_t(id), this, cStr(this->ident) );
          +  }
             
             Asset::~Asset ()
             { 
          diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp
          index c97af4844..a32111bfb 100644
          --- a/src/proc/asset.hpp
          +++ b/src/proc/asset.hpp
          @@ -246,7 +246,7 @@ namespace asset
                  *  May be empty. The head of this list can be considered the primary prerequisite
                  */
                 vector >  
          -      getParents ()  const;
          +      getParents ()  const;                 ////////////////TODO: better const vector, and return a ref!
                 
                 /** All the other assets requiring this asset to be functional. 
                  *  For example, all the clips depending on a given media file. 
          diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp
          index b01ba5155..dc46f96d7 100644
          --- a/src/proc/asset/clip.cpp
          +++ b/src/proc/asset/clip.cpp
          @@ -26,7 +26,44 @@
           namespace asset
             {
             
          -  /** */
          +  /** Directly object creating specialisation of the 
          +   *  asset::Media interface method: immediately starting
          +   *  out from this asset::Clip and doing the actual 
          +   *  MObject-creation in case there isn't already 
          +   *  a clip-MO linked with this Clip Asset. 
          +   */
          +  Media::PClipMO 
          +  Clip::createClip ()
          +  {
          +    if (!this.clipMO_)
          +      this.clipMO_ = MObject::create(
          +                       AssetManager::instance()
          +                          .getAsset (this.getID()));
          +    
          +    return this.clipMO_;
          +  }
          +  
          +  
          +  /** return this wrapped into a shared ptr,
          +   *   because it's already the desired asset::Clip
          +   */
          +  Media::PClip
          +  Clip::getClipAsset ()
          +  {
          +    return PClip (AssetManager::instance()
          +                    .getAsset (this.getID()));
          +  }
          +  
          +  
          +  /** specialisation delegating the decision to
          +   *  the media asset referred by this clip
          +   */ 
          +  Media::PMedia
          +  Clip::checkCompound ()
          +  {
          +    return this.source_.checkCompound();
          +  }
          +
           
           
           
          diff --git a/src/proc/asset/clip.hpp b/src/proc/asset/clip.hpp
          index fea774b49..e39ae34eb 100644
          --- a/src/proc/asset/clip.hpp
          +++ b/src/proc/asset/clip.hpp
          @@ -35,9 +35,21 @@ namespace asset
              */
             class Clip : public Media
               {
          -    protected:
          -      /**media source of this clip  */
          -      const Media* source;
          +      /** media source of this clip  */
          +      const Media& source_;
          +      
          +      /** the corresponding (dependant) clip-MO */
          +      PClipMO clipMO_;
          +      
          +    public:
          +      virtual PClipMO createClip ();
          +      virtual PMedia checkCompound ();
          +      
          +    private:
          +      Clip (const Media& mediaref) : source_(mediaref) {};
          +      friend class MediaFactory;
          +      
          +      virtual PClip getClipAsset ();
           
               };
               
          diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp
          index 6be2d4f3b..c88bdbfc0 100644
          --- a/src/proc/asset/media.cpp
          +++ b/src/proc/asset/media.cpp
          @@ -26,6 +26,7 @@
           #include "proc/asset/clip.hpp"
           #include "proc/asset/unknown.hpp"
           #include "proc/mobject/session/clip.hpp"
          +#include "proc/mobject/session/mobjectfactory.hpp"
           #include "common/util.hpp"
           #include "nobugcfg.h"
           
          @@ -62,21 +63,44 @@ namespace asset
             
             
             
          -  typedef shared_ptr PClip;
          -  typedef shared_ptr PProcPatt;
             
          -  
          -  PClip 
          +  Media::PClipMO
             Media::createClip ()
             {
          -    UNIMPLEMENTED ("create clip from media asset");
          -    PClip clip; //TODO:null
          +    PClip clipAsset (getClipAsset()); 
          +    PClipMO clipMO = clipAsset->createClip();
               
          -    ENSURE (clip);
          +    ENSURE (clipMO->isValid());
               return clip;
             }
             
          -  PProcPatt
          +  
          +  /** @internal used to either create an asset::Clip denoting the whole media,
          +   *            or to get the right reference to some already existing asset::Clip,
          +   *            especially when this media is part of a compound (multichannel) media.
          +   */
          +  Media::PClip
          +  Media::getClipAsset ()
          +  {
          +    if (PMedia parent = this.checkCompound())
          +      return parent->getClipAsset();
          +    else
          +      return Media::create(*this);
          +  }
          +  
          +  
          +  Media::PMedia
          +  Media::checkCompound()
          +  {
          +    PAsset parents = this.getParents();
          +    PMedia parent(0);
          +    if ( !isnil (parents))  // primary parent is a media asset?
          +       parent = dynamic_pointer_cast (parents[0]);
          +    return parent;
          +  }
          +  
          +  
          +  Media::PProcPatt
             Media::howtoProc ()
             {
               UNIMPLEMENTED ("calculate and return processing pattern for media asset");
          @@ -120,6 +144,7 @@ namespace asset
                 {
                   if (isnil (key.name)) key.name=extractName(file);
                   TODO ("file exists?");
          +        TODO ("detecting and wiring multichannel compound media!");
                   pM = new Media (key,file); 
                 }
               ASSERT (pM);
          @@ -170,6 +195,32 @@ namespace asset
               if (!file) file = "";
               return operator() (key, string(file));
             }
          +  
          +  
          +  /** Factory method for creating a Clip asset based
          +   *  on the given Media asset. This asset::Clip can be used
          +   *  to create clip in the EDL covering the whole length of
          +   *  this media. 
          +   *  @throw Invalid if the given media asset is not top-level,
          +   *         but rather part or a multichannel (compound) media
          +   */
          +  shared_ptr&
          +  MediaFactory::operator() (const asset::Media& mediaref)  throw(cinelerra::error::Invalid)
          +  {
          +    if (mediaref.checkCompound())
          +      throw cinelerra::error::Invalid (CINELERRA_ERROR_PART_OF_COMPOUND, 
          +                                         format("Attempt to create a asset::Clip from the media %s, "
          +                                                "which is not toplevel but rather part or a compound "
          +                                                "(multichannel) media. Found parent Media %s.") 
          +                                                % mediaref 
          +                                                % string(mediaref.checkCompound()));
          +    asset::Clip* pC = new asset::Clip (mediaref);
          +    return AssetManager::instance().getAsset (pC->getID());
          +  }
          +  
          +  CINELERRA_ERROR_DEFINE (PART_OF_COMPOUND, "part of compound used as toplevel element");
          +  
          +
           
           
           } // namespace asset
          diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp
          index 8349e1d69..7e2f92178 100644
          --- a/src/proc/asset/media.hpp
          +++ b/src/proc/asset/media.hpp
          @@ -37,10 +37,10 @@
           
           #include "proc/asset.hpp"
           #include "common/factory.hpp"
          +#include "proc/mobject/mobject.hpp"
           
           
           
          -namespace mobject { namespace session { class Clip; }}
           
           namespace asset
             {
          @@ -69,6 +69,12 @@ namespace asset
                 string filename_;
                 
               public:
          +      typedef shared_ptr PMedia;
          +      typedef shared_ptr PClip;
          +      typedef shared_ptr PProcPatt;
          +      typedef mobject::Placement PClipMO;
          +     
          +      
                 static MediaFactory create;
                 const string& getFilename ()  const { return filename_; }
                 
          @@ -77,12 +83,36 @@ namespace asset
                     return static_cast& > (Asset::getID()); 
                   }
                 
          -      shared_ptr createClip ();
          -      shared_ptr howtoProc ();
          +      /** Service Access Point for creating a Clip entity usable within 
          +       *  the EDL/Session from a given Media or Clip Asset. As a sideeffect,
          +       *  a corresponding asset::Clip is created as well if necessary. 
          +       *  It is OK to use and throw away the returned Clip-MO, because
          +       *  it can be regenerated from the corresponding asset::Clip
          +       *  @return a Placement smart ptr owning the new Clip MObject 
          +       */
          +      PClipMO createClip ();
          +      
          +      /** Service Access Point for getting a processing template
          +       *  describing how to build the render nodes network 
          +       *  necessary for this Media or Clip. This includes
          +       *  Codecs and postprocessing (stretching, deinterlacing...)
          +       */
          +      PProcPatt howtoProc ();
                 
               protected:
                 Media (const Asset::Ident& idi, const string& file) : Asset(idi), filename_(file) {}
                 friend class MediaFactory;
          +      
          +      /** get or create the correct asset::Clip 
          +       *  corresponding to this media */
          +      virtual PClip getClipAsset ();
          +      
          +      /** predicate to decide if this asset::Media
          +       *  is part of a compound (multichannel) media.
          +       *  @return pointer to parent, or \code null
          +       */
          +      virtual PMedia checkCompound ();
          +
               };
               
               
          @@ -110,9 +140,14 @@ namespace asset
                 PType operator() (Asset::Ident& key, const char* file);  ///< convienience overload using C-String
                 PType operator() (const char* file, const Category& cat);
                 PType operator() (const char* file, asset::Kind);
          +      
          +      shared_ptr&
          +      operator() (const asset::Media& mediaref)  throw(cinelerra::error::Invalid);
           
               };
           
          +  CINELERRA_ERROR_DECLARE (PART_OF_COMPOUND);
          +    
               
               
               
          diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp
          index 89843b1d6..508962e94 100644
          --- a/src/proc/assetmanager.cpp
          +++ b/src/proc/assetmanager.cpp
          @@ -46,7 +46,7 @@ namespace asset
             {
             
             /** 
          -   * AssetManager error responses, cause by querying
          +   * AssetManager error responses, caused by querying
              * invalid Asset IDs from the internal DB.
              */ 
             class IDErr : public cinelerra::error::Invalid 
          diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp
          index 8afd1a53a..abc71445f 100644
          --- a/src/proc/assetmanager.hpp
          +++ b/src/proc/assetmanager.hpp
          @@ -102,7 +102,7 @@ namespace asset
                     throw(cinelerra::error::Invalid);
                 
                 /** deleter function used by the Asset smart pointers to delet Asset objects */
          -      static void destroy (Asset* m) { delete m; }
          +      static void destroy (Asset* aa) { delete aa; }
                 
                 friend Asset::Asset (const Asset::Ident& idi);
                 
          diff --git a/src/proc/mobject/mobject.cpp b/src/proc/mobject/mobject.cpp
          index 47b47a943..284d12f9c 100644
          --- a/src/proc/mobject/mobject.cpp
          +++ b/src/proc/mobject/mobject.cpp
          @@ -27,7 +27,10 @@
           namespace mobject
             {
           
          -  /** */
          +  /** Storage for the (single, static) MObject factory object.
          +   */
          +  session::MObjectFactory MObject::create;
          +
           
           
           } // namespace mobject
          diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp
          index 347d8e5a1..be7d10014 100644
          --- a/src/proc/mobject/mobject.hpp
          +++ b/src/proc/mobject/mobject.hpp
          @@ -69,6 +69,9 @@ namespace mobject
               public:
                 static session::MObjectFactory create;
                 
          +      /** MObject self-test (usable for asserting) */
          +      virtual bool isValid() =0;
          +      
                 virtual PAsset getMedia () =0; ///< @todo solve the reference/Interface problem concerning Placements, then push down
                 virtual Time& getLength() =0; ///< @todo how to deal with the time/length field??
           
          diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp
          index 4d8a2ac4c..77e38174b 100644
          --- a/src/proc/mobject/placement.hpp
          +++ b/src/proc/mobject/placement.hpp
          @@ -90,9 +90,11 @@ namespace mobject
                 virtual MO * 
                 operator-> ()  const 
                   { 
          +          ENSURE (this.get()); 
                     return shared_ptr::operator-> (); 
                   }      
                 
          +      
                 /** interface for defining the kind of placement
                  *  to employ, and for controling any additional
                  *  constraints and properties. 
          diff --git a/src/proc/mobject/session/abstractmo.hpp b/src/proc/mobject/session/abstractmo.hpp
          index e0c1867d2..302bf2914 100644
          --- a/src/proc/mobject/session/abstractmo.hpp
          +++ b/src/proc/mobject/session/abstractmo.hpp
          @@ -40,9 +40,9 @@ namespace mobject
                   shared_ptr placement_;
                   
                 public:
          +        
                   /* some dummy implementations used to make the code compile... */
                   
          -        virtual shared_ptr& getPlacement () { return placement_; }
                   virtual Time& getLength()                      { return length; }
                   virtual PAsset getMedia ()                        
                     { 
          diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp
          index 7fbb30dcb..2502fc176 100644
          --- a/src/proc/mobject/session/clip.cpp
          +++ b/src/proc/mobject/session/clip.cpp
          @@ -28,7 +28,26 @@ namespace mobject
             namespace session
               {
           
          -    /** */
          +    /** new clip-MO linked with the given asset::Clip.
          +     *  Initially, this clip will cover the whole source media length. 
          +     */
          +    Clip::Clip (PClipAsset& mediaDef)
          +      : start_(0),
          +        mediaDef_(mediaDef)
          +    {
          +      this.setupLength();
          +    }
          +    
          +    
          +    
          +    void 
          +    Clip::setupLength()
          +    {
          +      UNIMPLEMENTED ("calculate the length of a clip and set length field");
          +      // will use mediaDef to query media parameters....
          +    }
          +
          +
           
           
           
          diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp
          index 316cbc435..fb0d00b9a 100644
          --- a/src/proc/mobject/session/clip.hpp
          +++ b/src/proc/mobject/session/clip.hpp
          @@ -54,7 +54,15 @@ namespace mobject
                   Time start;
           
                   //TODO: where to put the duration ???
          +        
          +        PClipAsset mediaDef_;
           
          +        Clip (PClipAsset& mediaDef);
          +        friend class MObjectFactory;
          +        
          +        
          +        virtual void setupLength();
          +        
                 };
                 
           
          diff --git a/src/proc/mobject/session/mobjectfactory.cpp b/src/proc/mobject/session/mobjectfactory.cpp
          index 553dc54c5..b407f908e 100644
          --- a/src/proc/mobject/session/mobjectfactory.cpp
          +++ b/src/proc/mobject/session/mobjectfactory.cpp
          @@ -43,7 +43,7 @@ namespace mobject
                *  asset.
                */
               Placement   
          -    MObjectFactory::operator() (shared_ptr& mediaDef)
          +    MObjectFactory::operator() (PClipAsset& mediaDef)
               {
                 //TODO sholdin't we rather store a ref to the underlying media assset??
                 return Placement (new Clip (mediaDef));
          diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp
          index 9ec54c4ba..cca272ff3 100644
          --- a/src/proc/mobject/session/mobjectfactory.hpp
          +++ b/src/proc/mobject/session/mobjectfactory.hpp
          @@ -32,6 +32,7 @@ namespace asset
             {
             class Clip;
             class Effect;
          +  
             }
           
           namespace mobject
          @@ -41,13 +42,14 @@ namespace mobject
               class Clip;
               class Effect;
           
          +    typedef shared_ptr PClipAsset;
           
               class MObjectFactory
                 {
                 public:
                   typedef Placement PType;
                   
          -        PType   operator() (const asset::Clip);
          +        PType   operator() (PClipAsset&);
                   PType operator() (const asset::Effect);
                   
                 };
          diff --git a/wiki/renderengine.html b/wiki/renderengine.html
          index d09474bec..c68c94676 100644
          --- a/wiki/renderengine.html
          +++ b/wiki/renderengine.html
          @@ -1397,16 +1397,19 @@ This Design strives to achieve a StrongSeparation between the low-level Structur
           [[Admin]]
           <<fullscreen>>
          -
          -
          Problem is: when removing an Asset, all corresponding MObjects need to disappear. This means, besides the obvious ~Ref-Link (MObject refering to an asset) we need backlinks or a sort of registry. And still worse: we need to remove the affetcted MObject from the object network in the EDL and rebuild the Fixture...
          +
          +
          Problem is: when removing an Asset, all corresponding MObjects need to disappear. This means, besides the obvious ~Ref-Link (MObject referring to an asset) we need backlinks or a sort of registry. And still worse: we need to remove the affected MObject from the object network in the EDL and rebuild the Fixture...
          +
          +&rarr; for a general design discussion see [[Relation of Clip and Asset|RelationClipAsset]]
           
           As a //first shot// Ichthyo considers the following approach:
          -* all references between MObjects and Assets are implemented as refcounting boost::shared_ptr
          +* all references between MObjects and Assets are implemented as __refcounting__ boost::shared_ptr
          +* the opposite direction is also a __strong references__, effectively keeping the clip-MO alive even if it is no longer in use in the session (note this is a cyclic dependency that needs to be actively broken on deletion). This design decision is based on  logical considerations (&rarr; see "deletions, Model-2" [[here|RelationClipAsset]]). The back-link is needed only for clean deletion of Assets and for GUI search functions.
           * MObjects and Assets implement an {{{unlink()}}} function releasing the internal links to other entities.
           * Instead of a delete, we call this unlink() function and let the shared_ptr handle the actual deletion.
           * we don't use a registry, rather we model the real dependencies by individual dependency links. So a MediaAsset gets links to all Clips created from this Asset and by traversing this tree, we can handle the deletion
           * after the deletion, the Fixture needs to be rebuilt.
          -* but any render processes still can have pointers to the Asset to be removed, and the shared_ptr will ensure, that the refered objects stay alive as long as needed.
          +* but any render processes still can have pointers to the Asset to be removed, and the shared_ptr will ensure, that the referred objects stay alive as long as needed.
           
           {{red{to be considered in more detail later}}}
           
          @@ -2085,7 +2088,7 @@ DAMAGE. The fact of being placed in the [[Session|SessionOverview]]/[[EDL]]is constitutive for all sorts of [[MObject]]s, without Placement they make no sense. Thus &mdash; technically &mdash; Placements act as ''smart pointers''. Of course, there are several kinds of Placements and they are templated on the type of MObject they are refering to. Placements can be //aggregated// to increasingly constrain the resulting "location" of the refered ~MObject. See &rarr; [[handling of Placements|PlacementHandling]] for more details
          -
          +
          [[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length). Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object.
           
           Actually, the way each Placement locates its subject is implemented by one or several small LocatingPin objects, where subclasses of LocatingPin implement the various differend methods of placing and resolving the final location. Notably, we can give a ~FixedLocation or we can atach to another ~MObject to get a ~RelativeLocation, etc.
          @@ -2395,6 +2398,26 @@ config.macros.rssFeedUpdate = {
           //}}}
           
          +
          +
          What is the Role of the asset::Clip and how exactly are Assets and (Clip)-MObjects related?
          +
          +First of all: ~MObjects are the dynamic/editing/manipulation view, while Assets are the static/bookkeeping/searching/information view of the same entities. Thus, the asset::Clip contains the general configuration, the ref to the media and descriptive properties, while all parameters being "manipulated" belong to the session::Clip (MObject). Besides that, the practical purpose of asset::Clip is that you can save and remember some selection as a Clip (Asset), maybe even attach some informations or markup to it, and later be able to (re)create a editable representation in the Session (the GUI could implement this by allowing to drag from the asset::Clip GUI representation to the timeline window)
          +
          +!!dependencies
          +The session::Clip (frequently called "clip-MO", i.e. the MObject) //depends on the Asset.// It can't exist without the Asset, because the Asset is needed for rendering. The other direction is different: the asset::Clip knows that there is a dependant clip-MO, there could be //at most one// such clip-MO depending on the Asset, but the Asset can exist without the clip-MO (it gives the possibility to re-create the clip-MO).
          +
          +!!deletions
          +When the Asset or the corresponding asset::Media is deleted, the dependant clip-MO has to disappear. And the opposite direction?
          +* Model-1: asset::Clip has a weak ref to the clip-MO. Consequently, the clip-MO can go out of scope and disappear, so the asset::Clip has to maintain the information of the clip's dimensions (source position and length) somewhere. Because of MultichannelMedia, this is not so simple as it may look at first sight.
          +* Model-2: asset::Clip holds a smart ptr to the clip-MO, thus effectively keeping it alive. __obviously the better choice__
          +In either case, we have to solve the ''problem of clip asset proliferation''
          +
          +!!multiplicity and const-ness
          +The link between ~MObject and Asset should be {{{const}}} in both directions (to enforce the separation of concerns). So the Asset can't //edit// the clip and the clip can't change the media parameters.
          +
          +The relation logical relation, but it is not strictly 1:1 because typical media are [[multichannel|MultichannelMedia]]. Even if the media is compound, there is //only one asset::Clip//, because in the logical view we have only one "clip-thing". On the other hand, in the Session/EDL, we have a compound clip ~MObject comprised of several elementary clip objects, each of which will refer to its own sub-media (channel) within the compound media (and don't forget, this structure can be tree-like)
          +{{red{open question:}}} do the clip-MO's of the individual channels refer directly to asset::Media? does this mean the relation is different from the top level, where we have a relation to a asset::Clip??
          +
          The Render Engine is the part of the application doing the actual video calculations. Its operations are guided by the Objects and Parameters edited by the user in [[the EDL|EDL]] and it retrieves the raw audio and video data from the [[Data backend|backend.html]]. Because the inner workings of the Render Engine are closely related to the structures used in the EDL, this design covers [[this aspect|MObjects]] as well.
           
          
          From c58fd16edba570b0e0f3a0ef225953c24e59c32a Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Mon, 22 Oct 2007 05:15:08 +0200
          Subject: [PATCH 08/22] WIP implement some Placement implementation
          
          ---
           doc/devel/uml/fig131333.png                   | Bin 0 -> 9210 bytes
           doc/devel/uml/index.html                      |  19 ++-
           doc/devel/uml/index_67.html                   |  41 ++++--
           doc/devel/uml/index_77.html                   |   1 +
           doc/devel/uml/index_83.html                   |   4 +-
           doc/devel/uml/objectdiagrams.html             |   1 +
           src/common/time.hpp                           |   6 +-
           src/proc/mobject/placement.hpp                |   7 +-
           src/proc/mobject/session/fixedlocation.cpp    |  16 +++
           src/proc/mobject/session/fixedlocation.hpp    |  10 +-
           src/proc/mobject/session/locatingpin.cpp      | 133 +++++++++++++++++-
           src/proc/mobject/session/locatingpin.hpp      |  87 +++++++++++-
           src/proc/mobject/session/relativelocation.cpp |  12 +-
           src/proc/mobject/session/relativelocation.hpp |   7 +-
           uml/cinelerra3/128261                         |  97 ++++++++++++-
           uml/cinelerra3/129285                         |   2 +-
           uml/cinelerra3/131333.diagram                 |  62 ++++++++
           uml/cinelerra3/cinelerra3.prj                 |   2 +-
           wiki/renderengine.html                        |  11 +-
           19 files changed, 473 insertions(+), 45 deletions(-)
           create mode 100644 doc/devel/uml/fig131333.png
           create mode 100644 uml/cinelerra3/131333.diagram
          
          diff --git a/doc/devel/uml/fig131333.png b/doc/devel/uml/fig131333.png
          new file mode 100644
          index 0000000000000000000000000000000000000000..2b4a00db7cbdd08ea82b71dc399f5a013978c4ae
          GIT binary patch
          literal 9210
          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
          
          literal 0
          HcmV?d00001
          
          diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html
          index c8908c30e..6d7dfdc87 100644
          --- a/doc/devel/uml/index.html
          +++ b/doc/devel/uml/index.html
          @@ -112,7 +112,7 @@ Documentation
           
           
          Artifact Cinelerra3

          Depends on common

          Depends on gui

          Depends on proc

          Depends on backend

          the main executable to be built

          -

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

          +

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

          Artifact main

          Artifact source

          @@ -801,6 +801,23 @@ reuse exiting Engine

        Selection :

          Transformation
          + +

          2.2.4 Use Case View config examples

          +
          + +

          +

          multichannel clip



          + +
          Class instance

          type :Clip

          +
          Class instance

          type :CompoundMedia

          +
          Class instance

          type :Media

          +
          Class instance

          type :Media

          +
          Class instance

          type :Media

          +
          Class instance

          type :CompoundClip

          +
          Class instance

          type :SimpleClip

          +
          Class instance

          type :SimpleClip

          +
          Class instance

          type :SimpleClip

          +
          Class instance

          type :Placement

          2.3 Package RenderEngine

          diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 198d3e6c7..f3abdcc6c 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -29,24 +29,34 @@ checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging Cinelerra3artifactthe main executable to be built cinelerra3package +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance clearoperationclear current session contents
          without resetting overall session config.
          Afterwards, the session will contain only one
          empty EDL, while all Assets are retained.
          Clipclassbookkeeping (asset) view of a media clip. clipartifactbookkeeping (asset) view of a media clip. @@ -69,6 +79,7 @@ compoundmediaartifacta special clip as a compound of several elementary media tracks,
          e.g. the individual media streams found in one media file ConditionclassI provided a reworked Condition class in my cinelerra2 repository Configclass +config examplesuse case view configureoperation configure Renderactivity configure Toolsopaque activity action @@ -78,8 +89,8 @@ connectopaque activity action Constraintclass Controllercomponent -controllerpackagesourcecode package

          The Processing and Render Controller,
          located within the MObject Subsystem Controllerpackage +controllerpackagesourcecode package

          The Processing and Render Controller,
          located within the MObject Subsystem Controller Entitiesclass diagram Controller Workingsclass view ControllerFacadeclassProvides unified access to the Proc-Subsystem Controller. Especially, this Facade class provides the functions to get a render engine to carry out actual renderings. diff --git a/doc/devel/uml/index_77.html b/doc/devel/uml/index_77.html index 997d703b9..775e82c1e 100644 --- a/doc/devel/uml/index_77.html +++ b/doc/devel/uml/index_77.html @@ -39,6 +39,7 @@ mobjectpackagesourcecode package

          MObject Subsystem
          including the Session (EDL), Builder and Processing Controller MObjectpackage MObjectclass +multichannel clipobject diagram MutexclassI provided a reworked Mutex class in my cinelerra2 repository diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index eb3719cf0..d8d717c8e 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -21,8 +21,8 @@ saveoperationcreate a complete, serialized representation
          of the current session config and contents.
          @todo how to serialize, prameters, return value? Schedulerclass segmentartifactSegment of the Timeline.
          Used at the moment (7/07) for partitioning the timeline/fixture into segments
          to be rendered by a specialized render node network for each, without the need
          to change any connections within a given segment.
          Note this concept may be superfluos alltogether; is a draft and the real
          use still needs to be worked out... -Segmentclass segment Toolactivity object +Segmentclass SegmentationToolclassTool implementation for deriving a partitioning of the current timeline such, that each segement has a constant configuration. "Constant" means here, that any remaining changes over time can be represented by automation solely, without the need to change the node connections. segmentationtoolartifactTool for creating a partitioning of the current timeline segmentsactivity object @@ -31,8 +31,8 @@ Service Componentsclass view Sessioncomponent sessionartifactInterface: the session edited by the user -Sessionclass view sessionpackagesourcecode package

          Everything concerning the EDL and Session, within the MObject Subsystem +Sessionclass view SessionclassPrimary Interface for all editing tasks.
          The session contains defaults, all the assets being edited, and a set of EDL with the individual MObjects to be manipulated and rendered. Session structureclass diagram sessionimplartifactholds the complete session data to be edited by the user diff --git a/doc/devel/uml/objectdiagrams.html b/doc/devel/uml/objectdiagrams.html index febb4a426..e45e944d2 100644 --- a/doc/devel/uml/objectdiagrams.html +++ b/doc/devel/uml/objectdiagrams.html @@ -20,6 +20,7 @@ EDL Example2More complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip Engine Example1Example1 (from EDL) continued: here the RenderEngine to be created by the Builder from the Input shown in Example1 Engine Example2Example2 (from EDL) continued: notably in this RenderEngine the Effect has been partitioned into 2 segments with constant configuration. +multichannel clip diff --git a/src/common/time.hpp b/src/common/time.hpp index e434d27ed..1e94effb7 100644 --- a/src/common/time.hpp +++ b/src/common/time.hpp @@ -40,10 +40,10 @@ namespace cinelerra */ class Time { - int dummy; + long dummy; public: - Time(int dum=0) : dummy(dum) {} - operator int () { return dummy; } + Time(long dum=0) : dummy(dum) {} + operator long () { return dummy; } }; } // namespace cinelerra diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 77e38174b..57722a6ad 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -73,7 +73,12 @@ namespace mobject class ExplicitPlacement; - + /** + * A refcounting Handle to an MObject of type MO, + * used to constrain or explicitly specify the + * location where the MObject is supposed to + * be within the Session/EDL + */ template class Placement : protected shared_ptr { diff --git a/src/proc/mobject/session/fixedlocation.cpp b/src/proc/mobject/session/fixedlocation.cpp index 08c19aa24..df5164c43 100644 --- a/src/proc/mobject/session/fixedlocation.cpp +++ b/src/proc/mobject/session/fixedlocation.cpp @@ -29,6 +29,22 @@ namespace mobject { /** */ + + void + FixedLocation::intersect (LocatingSolution& solution) const + { + REQUIRE (!solution.is_definite() && !solution.is_overconstrained()); + + TODO ("either set position or make overconstrained"); + if (solution.minTime <= this.time_) + solution.minTime = this.time_; + else + solution.impo = true; + if (solution.maxTime >= this.time_) + solution.maxTime = this.time_; + else + solution.impo = true; + } diff --git a/src/proc/mobject/session/fixedlocation.hpp b/src/proc/mobject/session/fixedlocation.hpp index e3a51056b..55f5a043d 100644 --- a/src/proc/mobject/session/fixedlocation.hpp +++ b/src/proc/mobject/session/fixedlocation.hpp @@ -37,9 +37,15 @@ namespace mobject * The most common case of positioning a MObject * in the EDL: directly specifying a constant position. */ - class FixedLocation : public LocatingPing + class FixedLocation : public LocatingPin { - /////////// + Time time_; + Track track_; + + protected: + FixedLocation (Time ti, Track tra) : time_(ti), track_(tra) {}; + + virtual void intersect (LocatingSolution&) const; }; diff --git a/src/proc/mobject/session/locatingpin.cpp b/src/proc/mobject/session/locatingpin.cpp index be9b2863c..6e27298e0 100644 --- a/src/proc/mobject/session/locatingpin.cpp +++ b/src/proc/mobject/session/locatingpin.cpp @@ -21,15 +21,144 @@ * *****************************************************/ -#include "proc/mobject/session/locatingpin.hpp" #include "proc/mobject/placement.hpp" +#include "proc/mobject/session/locatingpin.hpp" +#include "proc/mobject/session/fixedlocation.hpp" +#include "proc/mobject/session/relativelocation.hpp" namespace mobject { namespace session { - /** */ + /** it's OK to copy a LocainngPin, + * causing duplication of any chained lPins + */ + LocatingPin::LocatingPin (const LocatingPin& other) + : next_(other.next_) + { } + + + LocatingPin& + LocatingPin::operator= (const LocatingPin& other) + { + if (this!=other) + this.next_.reset (other.next_); + return *this; + } + + + LocatingPin& + LocatingPin::addChain (LocatingPin newLp) + { + REQUIRE (newLp); + REQUIRE (!newLp->next_, "can insert only single LocatingPins"); + + if (next_ && newLp->getPrioLevel() > next_->getPrioLevel()) + return next_->addChain (newLp); + else + { + scoped_ptr tmp_next (newLp); + tmp_next->next_.reset(this.next_); + this.next_.swap(tmp_next); + return *newLp; + } + } + + + /** implementing the core Placement functionality. + * By combining all the chained locating pins, try + * to get at a definite position (for this chain and + * consequently for the MObject handled by the enclosing + * Placement object). + * @todo this could/should be replaced by a full-blown + * constraint solver at some point in the future + */ + const FixedLocation + LocatingPin::resolve () const + { + LocatingSolution solution; + resolve (solution); + return FixedLocation (solution.getTime(), solution.getTrack()); + } + + + void + LocatingPin::resolve (LocatingSolution& solution) const + { + if (solution.is_definite() || solution.is_impossible()) + return; + this.intersect (solution); + if (this.next_ && + !(solution.is_definite() || solution.is_impossible()) + ) + next_->resolve(solution); + } + + + void + LocatingPin::intersect (LocatingSolution& solution) const + { + REQUIRE (!solution.is_definite() && !solution.is_impossible()); + // base class Implementation is NOP... + } + + + /** get some time value which could stand in for this + * solution. This doesn't imply this value is a solution, + * It's just a value we can use. At the moment (10/07), + * LocatingSolution is implemented as interval, and + * we return the lower bound here. + */ + LocatingPin::Time + LocatingPin::LocatingSolution::getTime() + { + return minTime; + } + + LocatingPin::Track + LocatingPin::LocatingSolution::getTrack() + { + UNIMPLEMENTED ("get effective Track number of Solution"); + } + + + bool + LocatingPin::LocatingSolution::is_definite() ///< found a solution? + { + return (minTime == maxTime && minTrack == maxTrack); + } + + bool + LocatingPin::LocatingSolution::is_impossible() + { + if (minTime > maxTime) impo = true; + TODO ("track???"); + return impo; + } + + + + + + + /* === Factory functions for adding LocatingPins === */ + + FixedLocation& + LocatingPin::operator() (Time, Track) + { + return static_cast + (this.addChain (*new FixedLocation (Time, Track))); + } + + + RelativeLocation& + LocatingPin::operator() (PMO refObj, Time offset=0) + { + return static_cast + (this.addChain (*new RelativeLocation (Time, Track))); + } + diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index 9d372111d..1637aa48f 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -21,6 +21,23 @@ */ +/** @file locatingpin.hpp + ** Implementing the Placement mechanics. The various specifications how + ** some MObject is to be placed (logically) within the EDL are given by small + ** LocatingPin objects forming a chain. For resolving the actual position, at the + ** moment (10/07) we use a preliminary implementation to support the most common + ** Placement types (fixed and relative). It is comprised of the nested LocatingSolution + ** and the functions FixedLocation#resolve(LocatingSolution&) and + ** RelativeLocation#resolve(LocatingSolution&) etc. If this is to be extended, + ** we'll need a real spacial discrete constraint solver (and it probably should be + ** a library implementation, because the problem is everything but trivial). + ** + */ + + + + + #ifndef MOBJECT_SESSION_LOCATINGPIN_H #define MOBJECT_SESSION_LOCATINGPIN_H @@ -42,22 +59,78 @@ namespace mobject class RelativeLocation; - struct LocatingPin + /** + * Positioning specification, possibliy chained + * to further specifications. The base class LocatingPin + * is a "no-op" specification which doesn't constrain the + * possible locations and thus can be embedded into pristine + * Placement by default. The Functor operators provide a + * way to add concrete positioning specifications, thereby + * defining the position of the MObject to be placed. + */ + class LocatingPin { protected: - typedef cinelerra::Time Time; - typedef session::Track* Track; + typedef cinelerra::Time Time; + typedef session::Track* Track; /** next additional Pin, if any */ - scoped_ptr next; - public: + scoped_ptr next_; - /* Factory functions for adding LocationPins */ + /** order to consider when resolving. 0=highest */ + virtual int getPrioLevel () const { return 0; } + + LocatingPin& addChain (LocatingPin); + void resolve (LocatingSolution&) const; + virtual void intersect (LocatingSolution&) const; + + public: + const FixedLocation resolve () const; + + /* Factory functions for adding LocatingPins */ FixedLocation& operator() (Time, Track); RelativeLocation& operator() (PMO refObj, Time offset=0); - + + LocatingPin (const LocatingPin&); + LocatingPin& operator= (const LocatingPin&); + virtual ~LocatingPin() {}; + + protected: + LocatingPin () {}; + + /** + * @internal helper for the (preliminary) + * position resolve() implementation. + * @todo we can't sensibly reason about tracks, + * because at the moment (10/07) we lack a track implementation... + */ + struct LocatingSolution + { + Time minTime; + Time maxTime; + Track minTrack; + Track maxTrack; + bool impo; + + LocatingSolution () + : minTime(-1e15), // TODO: better implementation of "unspecified..." + maxTime(+1e15), + minTrack(0), // TODO + maxTrack(0), + impo(false) + { } + + Time getTime(); + Track getTrack(); + + bool is_definite(); + bool is_impossible(); + }; }; + + + } // namespace mobject::session diff --git a/src/proc/mobject/session/relativelocation.cpp b/src/proc/mobject/session/relativelocation.cpp index 6fd934f12..a0e0daa25 100644 --- a/src/proc/mobject/session/relativelocation.cpp +++ b/src/proc/mobject/session/relativelocation.cpp @@ -1,5 +1,5 @@ /* - RelativePlacement - Placement implemnetaion providing various ways of attaching a MObject to another one + RelativeLocation - Placement implementation attaching MObjects relative to another one Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -21,7 +21,7 @@ * *****************************************************/ -#include "proc/mobject/session/relativeplacement.hpp" +#include "proc/mobject/session/relativelocation.hpp" #include "proc/mobject/mobject.hpp" namespace mobject @@ -29,7 +29,15 @@ namespace mobject namespace session { + void + RelativeLocation::intersect (LocatingSolution& solution) const + { + REQUIRE (!solution.is_definite() && !solution.is_overconstrained()); + + TODO ("either set position or make overconstrained"); + } + } // namespace mobject::session } // namespace mobject diff --git a/src/proc/mobject/session/relativelocation.hpp b/src/proc/mobject/session/relativelocation.hpp index 577c741f3..1c2003e22 100644 --- a/src/proc/mobject/session/relativelocation.hpp +++ b/src/proc/mobject/session/relativelocation.hpp @@ -49,14 +49,17 @@ namespace mobject }; protected: - MObject* anchor; + Placement anchor; ////////////TODO: ooooops, this is a nasty design problem!!! /** the kind of relation denoted by this Placement */ RelType relType; /** Offset the actual position by this (time) value relative to the anchor point. */ - cinelerra::Time offset; + Time offset; //TODO: suitable representation? + + + virtual void intersect (LocatingSolution&) const; }; diff --git a/uml/cinelerra3/128261 b/uml/cinelerra3/128261 index 9925728b7..10080e773 100644 --- a/uml/cinelerra3/128261 +++ b/uml/cinelerra3/128261 @@ -1,6 +1,6 @@ format 40 "MObject" // ProcessingLayer::MObject - revision 26 + revision 27 modified_by 5 "hiv" // class settings //class diagram settings @@ -1107,4 +1107,99 @@ ${inlines} package_ref 128901 // Builder package_ref 129029 // Controller + + usecaseview 128261 "config examples" + //use case diagram settings + package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow 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 + //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 + //object diagram settings + write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default + objectdiagram 131333 "multichannel clip" + write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default + size A4 + end + + classinstance 134661 "" + type class_ref 137349 // Clip + attributes + end + relations + end + end + + classinstance 134789 "" + type class_ref 138501 // CompoundMedia + attributes + end + relations + end + end + + classinstance 134917 "" + type class_ref 136709 // Media + attributes + end + relations + end + end + + classinstance 135045 "" + type class_ref 136709 // Media + attributes + end + relations + end + end + + classinstance 135173 "" + type class_ref 136709 // Media + attributes + end + relations + end + end + + classinstance 135301 "" + type class_ref 138629 // CompoundClip + attributes + end + relations + end + end + + classinstance 135429 "" + type class_ref 138885 // SimpleClip + attributes + end + relations + end + end + + classinstance 135557 "" + type class_ref 138885 // SimpleClip + attributes + end + relations + end + end + + classinstance 135685 "" + type class_ref 138885 // SimpleClip + attributes + end + relations + end + end + + classinstance 135813 "" + type class_ref 128645 // Placement + attributes + end + relations + end + end + end end diff --git a/uml/cinelerra3/129285 b/uml/cinelerra3/129285 index ec9e7d7fc..551a99b4b 100644 --- a/uml/cinelerra3/129285 +++ b/uml/cinelerra3/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 5 + revision 6 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/cinelerra3/131333.diagram b/uml/cinelerra3/131333.diagram new file mode 100644 index 000000000..c53581101 --- /dev/null +++ b/uml/cinelerra3/131333.diagram @@ -0,0 +1,62 @@ +format 40 + +classinstancecanvas 128005 classinstance_ref 134661 // + xyz 233 116 2000 + end +classinstancecanvas 128133 classinstance_ref 134789 // + xyz 297 53 2000 + end +classinstancecanvas 128261 classinstance_ref 134917 // + xyz 335 112 2000 + end +classinstancecanvas 128389 classinstance_ref 135045 // + xyz 335 144 2000 + end +classinstancecanvas 128517 classinstance_ref 135173 // + xyz 335 177 2000 + end +fragment 128773 "" + xyzwh 311 90 1994 83 139 +end +classinstancecanvas 129157 classinstance_ref 135301 // + xyz 65 116 2000 + end +classinstancecanvas 129285 classinstance_ref 135429 // + xyz 95 176 2000 + end +classinstancecanvas 129413 classinstance_ref 135557 // + xyz 95 208 2000 + end +classinstancecanvas 129541 classinstance_ref 135685 // + xyz 95 241 2000 + end +fragment 129669 "" + xyzwh 70 153 1994 93 136 +end +classinstancecanvas 129925 classinstance_ref 135813 // + xyz 75 33 2000 + end +fragment 130181 "EDL" + xyzwh 12 12 2000 167 305 +end +fragment 130437 "asset management" + xyzwh 221 12 2005 184 236 +end +objectlinkcanvas 128645 norel + from ref 128133 z 1999 to ref 128261 + no_role_a no_role_b +objectlinkcanvas 128901 norel + geometry VH + from ref 128005 z 1999 to point 256 64 + line 129029 z 1999 to ref 128133 + no_role_a no_role_b +objectlinkcanvas 129797 norel + from ref 129157 z 1999 to ref 129285 + no_role_a no_role_b +objectlinkcanvas 130053 norel + from ref 129925 z 1999 to ref 129157 + no_role_a no_role_b +objectlinkcanvas 130309 norel + from ref 129157 z 1999 to ref 128005 + no_role_a no_role_b +end diff --git a/uml/cinelerra3/cinelerra3.prj b/uml/cinelerra3/cinelerra3.prj index 62217077f..78317c6ff 100644 --- a/uml/cinelerra3/cinelerra3.prj +++ b/uml/cinelerra3/cinelerra3.prj @@ -1,6 +1,6 @@ format 40 "cinelerra3" - revision 35 + revision 36 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index c68c94676..384c32e10 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -1459,7 +1459,7 @@ For the case in question this seems to be the ''resource allocation is construct And, last but not least, doing all actual allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides that, the ProcLayer code shouldn't issue "new" and "delete", rather it should use some central [[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. -
          +
          Based on practical experiences, Ichthyo tends to consider Multichannel Media as the base case, while counting media files providing just one single media stream as exotic corner cases. This may seem counter intuitive at first sight; you should think of  it as an attempt to avoid right from start some of the common shortcomings found in many video editors, especially
           * having to deal with keeping a "link" between audio and video clips
           * silly limitations on the supported audio setups (e.g. "sound is mono, stereo or Dolby-5.1")
          @@ -1467,6 +1467,7 @@ And, last but not least, doing all actual allocations is the job of the backend.
           * inability to edit stereoscopic (3D) video in a natural fashion
           
           !Compound Media
          +[>img[Outline of the Build Process|uml/fig131333.png]]
           Basically, each [[media asset|MediaAsset]] is considered to be a compound of several elementary media (tracks), possibly of various different media kinds. Adding support for placeholders (''proxy clips'') at some point in future will add still more complexity (because then there will be even dependencies between some of these elementary media). To handle, edit and render compound media, we need to impose some structural limitations. But anyhow, we try to configure as much as possible already at the "asset level" and make the rest of the proc layer behave just according to the configuration given with each asset.
           
           So, when creating a clip out of such a compound media asset, the clip has to be a compound of elementary clips mirroring the given media asset's structure. Besides, it should be possible to //detach// and //attach// elementary clips from a compound clip. On the other hand, the [[Fixture]] created from the current state of the [[EDL]] is explicit to a great extent. So, in the Fixture we deal only with elementary clips placed to absolute positions, and thus the builder will see only simple non-compound clips and translate them into the corresponding source reading nodes.
          @@ -2398,7 +2399,7 @@ config.macros.rssFeedUpdate = {
           //}}}
           
          -
          +
          What is the Role of the asset::Clip and how exactly are Assets and (Clip)-MObjects related?
           
           First of all: ~MObjects are the dynamic/editing/manipulation view, while Assets are the static/bookkeeping/searching/information view of the same entities. Thus, the asset::Clip contains the general configuration, the ref to the media and descriptive properties, while all parameters being "manipulated" belong to the session::Clip (MObject). Besides that, the practical purpose of asset::Clip is that you can save and remember some selection as a Clip (Asset), maybe even attach some informations or markup to it, and later be able to (re)create a editable representation in the Session (the GUI could implement this by allowing to drag from the asset::Clip GUI representation to the timeline window)
          @@ -2413,9 +2414,9 @@ When the Asset or the corresponding asset::Media is deleted, the dependant clip-
           In either case, we have to solve the ''problem of clip asset proliferation''
           
           !!multiplicity and const-ness
          -The link between ~MObject and Asset should be {{{const}}} in both directions (to enforce the separation of concerns). So the Asset can't //edit// the clip and the clip can't change the media parameters.
          -
          -The relation logical relation, but it is not strictly 1:1 because typical media are [[multichannel|MultichannelMedia]]. Even if the media is compound, there is //only one asset::Clip//, because in the logical view we have only one "clip-thing". On the other hand, in the Session/EDL, we have a compound clip ~MObject comprised of several elementary clip objects, each of which will refer to its own sub-media (channel) within the compound media (and don't forget, this structure can be tree-like)
          +The link between ~MObject and Asset should be {{{const}}}, so the clip can't change the media parameters. Because of separation of concerns, it would be desirable that the Asset can't //edit// the clip either (meaning {{{const}}} in the opposite direction as well). But unfortunately the asset::Clip is in power to delete the clip-MO and, moreover, handles out a smart ptr ([[Placement]]) referring to the clip-MO, which can (and should) be used to place the clip-MO within the EDL and to manipulate it consequently...
          +[>img[Outline of the Build Process|uml/fig131333.png]]
          +At first sight the link between asset and clip-MO is a simple logical relation between entities, but it is not strictly 1:1 because typical media are [[multichannel|MultichannelMedia]]. Even if the media is compound, there is //only one asset::Clip//, because in the logical view we have only one "clip-thing". On the other hand, in the Session/EDL, we have a compound clip ~MObject comprised of several elementary clip objects, each of which will refer to its own sub-media (channel) within the compound media (and don't forget, this structure can be tree-like)
           {{red{open question:}}} do the clip-MO's of the individual channels refer directly to asset::Media? does this mean the relation is different from the top level, where we have a relation to a asset::Clip??
          From 242640c4fdc91e6a791767a71be516a2633755fa Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 10 Nov 2007 02:27:16 +0100 Subject: [PATCH 09/22] some fixes --- src/proc/mobject/session/fixedlocation.cpp | 8 +++- src/proc/mobject/session/fixedlocation.hpp | 4 ++ src/proc/mobject/session/locatingpin.cpp | 43 ++++++++++++++----- src/proc/mobject/session/locatingpin.hpp | 12 ++++-- src/proc/mobject/session/relativelocation.cpp | 7 +++ src/proc/mobject/session/relativelocation.hpp | 4 ++ wiki/renderengine.html | 4 +- 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/proc/mobject/session/fixedlocation.cpp b/src/proc/mobject/session/fixedlocation.cpp index df5164c43..c1cbefa64 100644 --- a/src/proc/mobject/session/fixedlocation.cpp +++ b/src/proc/mobject/session/fixedlocation.cpp @@ -28,8 +28,14 @@ namespace mobject namespace session { - /** */ + LocatingPin* + LocatingPin::clone () + { + return new FixedLocation (*this); + } + + /** */ void FixedLocation::intersect (LocatingSolution& solution) const { diff --git a/src/proc/mobject/session/fixedlocation.hpp b/src/proc/mobject/session/fixedlocation.hpp index 55f5a043d..19a71e608 100644 --- a/src/proc/mobject/session/fixedlocation.hpp +++ b/src/proc/mobject/session/fixedlocation.hpp @@ -46,6 +46,10 @@ namespace mobject FixedLocation (Time ti, Track tra) : time_(ti), track_(tra) {}; virtual void intersect (LocatingSolution&) const; + + public: + virtual LocatingPin* clone () const; + }; diff --git a/src/proc/mobject/session/locatingpin.cpp b/src/proc/mobject/session/locatingpin.cpp index 6e27298e0..e43b4946c 100644 --- a/src/proc/mobject/session/locatingpin.cpp +++ b/src/proc/mobject/session/locatingpin.cpp @@ -30,12 +30,21 @@ namespace mobject { namespace session { + inline LocatingPin* + cloneChain (scoped_ptr& chain) + { + if (!chain) + return 0; + else + return chain->clone(); + } + /** it's OK to copy a LocainngPin, * causing duplication of any chained lPins */ LocatingPin::LocatingPin (const LocatingPin& other) - : next_(other.next_) + : next_(cloneChain (other.next_)) { } @@ -43,13 +52,21 @@ namespace mobject LocatingPin::operator= (const LocatingPin& other) { if (this!=other) - this.next_.reset (other.next_); + this.next_.reset (cloneChain (other.next_)); return *this; } + LocatingPin* + LocatingPin::clone () + { + return new LocatingPin(*this); + } + + + LocatingPin& - LocatingPin::addChain (LocatingPin newLp) + LocatingPin::addChain (LocatingPin* newLp) ///< @note we take ownership of newLp { REQUIRE (newLp); REQUIRE (!newLp->next_, "can insert only single LocatingPins"); @@ -59,7 +76,7 @@ namespace mobject else { scoped_ptr tmp_next (newLp); - tmp_next->next_.reset(this.next_); + tmp_next->next_.swap(this.next_); this.next_.swap(tmp_next); return *newLp; } @@ -83,15 +100,21 @@ namespace mobject } + inline bool + still_to_solve (LocatingPin::LocatingSolution& solution) + { + return !(solution.is_definite() || solution.is_impossible()); + } + + void LocatingPin::resolve (LocatingSolution& solution) const { - if (solution.is_definite() || solution.is_impossible()) + if (!still_to_solve(solution)) return; this.intersect (solution); if (this.next_ && - !(solution.is_definite() || solution.is_impossible()) - ) + still_to_solve (solution)) next_->resolve(solution); } @@ -99,7 +122,7 @@ namespace mobject void LocatingPin::intersect (LocatingSolution& solution) const { - REQUIRE (!solution.is_definite() && !solution.is_impossible()); + REQUIRE (still_to_solve (solution)); // base class Implementation is NOP... } @@ -148,7 +171,7 @@ namespace mobject LocatingPin::operator() (Time, Track) { return static_cast - (this.addChain (*new FixedLocation (Time, Track))); + (this.addChain (new FixedLocation (Time, Track))); } @@ -156,7 +179,7 @@ namespace mobject LocatingPin::operator() (PMO refObj, Time offset=0) { return static_cast - (this.addChain (*new RelativeLocation (Time, Track))); + (this.addChain (new RelativeLocation (Time, Track))); } diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index 1637aa48f..5d0e3a1c5 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -29,8 +29,8 @@ ** Placement types (fixed and relative). It is comprised of the nested LocatingSolution ** and the functions FixedLocation#resolve(LocatingSolution&) and ** RelativeLocation#resolve(LocatingSolution&) etc. If this is to be extended, - ** we'll need a real spacial discrete constraint solver (and it probably should be - ** a library implementation, because the problem is everything but trivial). + ** we'll need a real spatial discrete constraint solver (and this probably will be + ** some library implementation, because the problem is anything but trivial). ** */ @@ -66,7 +66,10 @@ namespace mobject * possible locations and thus can be embedded into pristine * Placement by default. The Functor operators provide a * way to add concrete positioning specifications, thereby - * defining the position of the MObject to be placed. + * defining the position of the MObject to be placed. + * + * @note to the implementer of subclasses: LocatingPins are + * copyable and need to handle cloning (incl the chain) */ class LocatingPin { @@ -80,7 +83,7 @@ namespace mobject /** order to consider when resolving. 0=highest */ virtual int getPrioLevel () const { return 0; } - LocatingPin& addChain (LocatingPin); + LocatingPin& addChain (LocatingPin*); void resolve (LocatingSolution&) const; virtual void intersect (LocatingSolution&) const; @@ -94,6 +97,7 @@ namespace mobject LocatingPin (const LocatingPin&); LocatingPin& operator= (const LocatingPin&); + virtual LocatingPin* clone () const; virtual ~LocatingPin() {}; protected: diff --git a/src/proc/mobject/session/relativelocation.cpp b/src/proc/mobject/session/relativelocation.cpp index a0e0daa25..73c655d80 100644 --- a/src/proc/mobject/session/relativelocation.cpp +++ b/src/proc/mobject/session/relativelocation.cpp @@ -29,6 +29,13 @@ namespace mobject namespace session { + LocatingPin* + LocatingPin::clone () + { + return new RelativeLocation (*this); + } + + void RelativeLocation::intersect (LocatingSolution& solution) const { diff --git a/src/proc/mobject/session/relativelocation.hpp b/src/proc/mobject/session/relativelocation.hpp index 1c2003e22..eca3d9e24 100644 --- a/src/proc/mobject/session/relativelocation.hpp +++ b/src/proc/mobject/session/relativelocation.hpp @@ -60,6 +60,10 @@ namespace mobject virtual void intersect (LocatingSolution&) const; + + + public: + virtual LocatingPin* clone () const; }; diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 384c32e10..9411f408a 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -2741,8 +2741,8 @@ h1,h2,h3,h4,h5,h6 { /*}}}*/
          -
          -
          <<timeline better:true maxDays:28 maxEntries:20>>
          +
          +
          <<timeline better:true maxDays:55 maxEntries:30>>
          /***
          
          From 38236e607d19225165241b683bbf1b1afc54da63 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Sat, 10 Nov 2007 21:50:55 +0100
          Subject: [PATCH 10/22] some further cleanup
          
          ---
           src/common/util.hpp                           | 10 ++++++----
           src/proc/mobject/explicitplacement.hpp        | 16 +++++++++++-----
           src/proc/mobject/placement.hpp                |  4 ++--
           src/proc/mobject/session/allocation.cpp       |  9 ++++++++-
           src/proc/mobject/session/allocation.hpp       | 12 ++++++++----
           src/proc/mobject/session/fixedlocation.cpp    |  2 +-
           src/proc/mobject/session/fixedlocation.hpp    |  9 ++++++++-
           src/proc/mobject/session/locatingpin.cpp      |  2 ++
           src/proc/mobject/session/locatingpin.hpp      |  2 ++
           src/proc/mobject/session/relativelocation.cpp |  4 ++--
           10 files changed, 50 insertions(+), 20 deletions(-)
          
          diff --git a/src/common/util.hpp b/src/common/util.hpp
          index 9780fe65e..2e9f3dac9 100644
          --- a/src/common/util.hpp
          +++ b/src/common/util.hpp
          @@ -112,7 +112,7 @@ namespace util
             {
               return std::for_each (c.begin(),c.end(), doIt);
             }
          -   
          +  
             
             
             /** produce an identifier based on the given string.
          @@ -153,8 +153,8 @@ namespace util
           
            /* === some common macro definitions === */
           
          -/** supress "warning: unused variable" on vars, which
          - *  are introduced into a scope because of some sideeffect, i.e. Locking
          +/** supress "warning: unused variable" on vars, which are
          + *  introduced into a scope because of some sideeffect, i.e. Locking
            */
           #define SIDEEFFECT __attribute__ ((unused));
           
          @@ -162,7 +162,9 @@ namespace util
           #define STRINGIFY(TOKEN) __STRNGFY(TOKEN)
           #define __STRNGFY(TOKEN) #TOKEN
           
          -/** shortcut for subclass test, intended for assertions */
          +/** shortcut for subclass test, intended for assertions only.
          + *  @note it is considered bad style to use such in non-assertion code,
          + *        and we probably will enforce this design rule in future. */
           #define INSTANCEOF(CLASS, EXPR) (dynamic_cast (EXPR)) 
           
           #endif /*UTIL_HPP_*/
          diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp
          index 1e4f5beca..8896405a7 100644
          --- a/src/proc/mobject/explicitplacement.hpp
          +++ b/src/proc/mobject/explicitplacement.hpp
          @@ -53,19 +53,25 @@ namespace mobject
                 /** no need to resolve any further, as this ExplicitPlacement
                  *  already \i is the result of a resolve()-call.
                  */
          -      virtual const 
          +      virtual
                 ExplicitPlacement resolve ()  const 
                   { 
                     return *this; 
                   }
           
          -    private:
          -      ExplicitPlacement (Placement& base, Time ti, Track tra)
          +    protected:
          +      /*  @todo ichthyo considers a much more elegant implementation utilizing a subclass 
          +       *        of FixedLocation, which would serve as Placement::LocatingSolution, and
          +       *        would be used as LocatingPin::chain subobject as well, so that it could
          +       *        be initialized directly here in the ExplicitPlacement ctor. 
          +       *        (ichthyo: siehe Trac #100)
          +       */
          +      ExplicitPlacement (Placement& base, const session::FixedLocation found)
                   : Placement(base),
          -          time(ti), track(tra)
          +          time(found.time_), track(found.track_)
                   { };
                   
          -      friend class session::LocatingPin;
          +      friend ExplicitPlacement::resolve () const;
               };
           
           
          diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp
          index 57722a6ad..36fc216f9 100644
          --- a/src/proc/mobject/placement.hpp
          +++ b/src/proc/mobject/placement.hpp
          @@ -110,10 +110,10 @@ namespace mobject
                  *  by the various LocatingPin (\see #chain) and
                  *  provide the resulting (explicit) placement.
                  */
          -      virtual const ExplicitPlacement 
          +      virtual ExplicitPlacement
                 resolve ()  const 
                   { 
          -          return chain.resolve(); 
          +          return ExplicitPlacement (*this, chain.resolve()); 
                   }
                 
                 
          diff --git a/src/proc/mobject/session/allocation.cpp b/src/proc/mobject/session/allocation.cpp
          index a590756c3..a8082cdef 100644
          --- a/src/proc/mobject/session/allocation.cpp
          +++ b/src/proc/mobject/session/allocation.cpp
          @@ -28,7 +28,14 @@ namespace mobject
             namespace session
               {
           
          -    /** */
          +    /** @todo probably a placeholder and to be pushed down....*/
          +    void 
          +    Allocation::intersect (LocatingSolution& solution)  const
          +    {
          +      LocatingPin::intersect (solution);
          +      
          +      TODO ("work out how the Allocation types solve for the position...");
          +    }
           
           
           
          diff --git a/src/proc/mobject/session/allocation.hpp b/src/proc/mobject/session/allocation.hpp
          index 5bdd5b88c..209fc9406 100644
          --- a/src/proc/mobject/session/allocation.hpp
          +++ b/src/proc/mobject/session/allocation.hpp
          @@ -39,8 +39,8 @@ namespace mobject
           
           
               /**
          -     * Interface: any objective, constraint or wish of
          -     * placeing a MObject in a specific way.
          +     * Interface (abstract): any objective, constraint or wish
          +     * of placing a MObject in a specific way.
                */
               class Allocation : public LocatingPin
                 {
          @@ -49,9 +49,13 @@ namespace mobject
                    *  characterizing this allocaton, e.g. "t >= 10"
                    */
                   string repr;
          -
          +        
          +        virtual void intersect (LocatingSolution&)  const;
          +        
                 public:
          -        const string& getRepr () const { return repr; } 
          +        const string& getRepr () const { return repr; }
          +        
          +        virtual LocatingPin* clone ()  const = 0;
                 };
           
           
          diff --git a/src/proc/mobject/session/fixedlocation.cpp b/src/proc/mobject/session/fixedlocation.cpp
          index c1cbefa64..0a6753a71 100644
          --- a/src/proc/mobject/session/fixedlocation.cpp
          +++ b/src/proc/mobject/session/fixedlocation.cpp
          @@ -39,7 +39,7 @@ namespace mobject
               void 
               FixedLocation::intersect (LocatingSolution& solution)  const
               {
          -      REQUIRE (!solution.is_definite() && !solution.is_overconstrained());
          +      LocatingPin::intersect (solution);
                 
                 TODO ("either set position or make overconstrained");
                 if (solution.minTime <= this.time_)
          diff --git a/src/proc/mobject/session/fixedlocation.hpp b/src/proc/mobject/session/fixedlocation.hpp
          index 19a71e608..ca7254991 100644
          --- a/src/proc/mobject/session/fixedlocation.hpp
          +++ b/src/proc/mobject/session/fixedlocation.hpp
          @@ -30,18 +30,25 @@
           
           namespace mobject
             {
          +    class ExplicitPlacement; //TODO trac #100
          +    
             namespace session
               {
           
               /** 
                * The most common case of positioning a MObject
          -     * in the EDL: directly specifying a constant position. 
          +     * in the EDL: directly specifying a constant position.
          +     * @todo use a subclass to represent the LocatingSolution?
          +     *       would solve the construction of a ExplicitPlacement
          +     *       much more natural. (ichthyo: siehe trac #100) 
                */
               class FixedLocation : public LocatingPin
                 {
                   Time time_;
                   Track track_;
                   
          +        friend class ExplicitPlacement; //TODO trac #100
          +        
                 protected:
                   FixedLocation (Time ti, Track tra) : time_(ti), track_(tra) {};
                   
          diff --git a/src/proc/mobject/session/locatingpin.cpp b/src/proc/mobject/session/locatingpin.cpp
          index e43b4946c..a054b1736 100644
          --- a/src/proc/mobject/session/locatingpin.cpp
          +++ b/src/proc/mobject/session/locatingpin.cpp
          @@ -90,6 +90,8 @@ namespace mobject
                *  Placement object).
                *  @todo this could/should be replaced by a full-blown
                *        constraint solver at some point in the future
          +     *  @todo we are packing and unpacking the information (time,track)
          +     *        several times. Ichthyo considers a more elegant solution.
                */
               const FixedLocation
               LocatingPin::resolve ()  const
          diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp
          index 5d0e3a1c5..8f030fff3 100644
          --- a/src/proc/mobject/session/locatingpin.hpp
          +++ b/src/proc/mobject/session/locatingpin.hpp
          @@ -108,6 +108,8 @@ namespace mobject
                    * position resolve() implementation.
                    * @todo we can't sensibly reason about tracks, 
                    * because at the moment (10/07) we lack a track implementation...
          +         * @todo shouldn't we use a range-restriction LocatingPin (subclass)
          +         * to represent the to-be-found solution? (ichthyo: siehe Trac #100)
                    */  
                   struct LocatingSolution
                     {
          diff --git a/src/proc/mobject/session/relativelocation.cpp b/src/proc/mobject/session/relativelocation.cpp
          index 73c655d80..7439a9913 100644
          --- a/src/proc/mobject/session/relativelocation.cpp
          +++ b/src/proc/mobject/session/relativelocation.cpp
          @@ -39,8 +39,8 @@ namespace mobject
               void 
               RelativeLocation::intersect (LocatingSolution& solution)  const
               {
          -      REQUIRE (!solution.is_definite() && !solution.is_overconstrained());
          -      
          +      LocatingPin::intersect (solution);
          +        
                 TODO ("either set position or make overconstrained");
               }
           
          
          From 5c2fa504e72093422a83862ea4cfe7650f89c25c Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Sat, 10 Nov 2007 23:09:15 +0100
          Subject: [PATCH 11/22] WIP update test code to reflect the new placement
           properties. still have to convince the compiler that i am not a
           terrrorist....
          
          ---
           src/proc/mobject/mobject.hpp                         |  5 ++---
           src/proc/mobject/session/abstractmo.hpp              |  8 ++------
           src/proc/mobject/session/clip.cpp                    | 10 ++++++++++
           src/proc/mobject/session/clip.hpp                    | 11 +++++++++++
           src/proc/mobject/session/locatingpin.cpp             |  8 ++++++++
           src/proc/mobject/session/locatingpin.hpp             |  5 +++--
           src/proc/mobject/session/mobjectfactory.cpp          |  6 ++++--
           tests/components/proc/asset/makecliptest.cpp         |  4 ++--
           tests/components/proc/mobject/placementbasictest.cpp |  9 ++++-----
           9 files changed, 46 insertions(+), 20 deletions(-)
          
          diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp
          index be7d10014..1e18e09e8 100644
          --- a/src/proc/mobject/mobject.hpp
          +++ b/src/proc/mobject/mobject.hpp
          @@ -38,7 +38,7 @@ using std::tr1::shared_ptr;
           
           #include "proc/assetmanager.hpp"                
           using proc_interface::IDA;                // TODO finally not needed?
          -using proc_interface::PAsset;              //TODO: only temporarily
          +//using proc_interface::PAsset;              //TODO: only temporarily
           using proc_interface::AssetManager;
           
           namespace mobject
          @@ -70,9 +70,8 @@ namespace mobject
                 static session::MObjectFactory create;
                 
                 /** MObject self-test (usable for asserting) */
          -      virtual bool isValid() =0;
          +      virtual bool isValid()  const =0;
                 
          -      virtual PAsset getMedia () =0; ///< @todo solve the reference/Interface problem concerning Placements, then push down
                 virtual Time& getLength() =0; ///< @todo how to deal with the time/length field??
           
               };
          diff --git a/src/proc/mobject/session/abstractmo.hpp b/src/proc/mobject/session/abstractmo.hpp
          index 302bf2914..f73661d8a 100644
          --- a/src/proc/mobject/session/abstractmo.hpp
          +++ b/src/proc/mobject/session/abstractmo.hpp
          @@ -43,12 +43,8 @@ namespace mobject
                   
                   /* some dummy implementations used to make the code compile... */
                   
          -        virtual Time& getLength()                      { return length; }
          -        virtual PAsset getMedia ()                        
          -          { 
          -            UNIMPLEMENTED ("how to relate MObjects and media assets...");
          -            return AssetManager::instance().getAsset(IDA(0)); // KABOOM! (just to make it compile)
          -          }
          +        virtual Time& getLength() { return length; }
          +        
                 protected:
                   /** custom deleter func allowing class Placement 
                     *  to take ownership of MObjct instances
          diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp
          index 2502fc176..8314b13f6 100644
          --- a/src/proc/mobject/session/clip.cpp
          +++ b/src/proc/mobject/session/clip.cpp
          @@ -40,6 +40,16 @@ namespace mobject
               
               
               
          +    /** implementing the common MObject self test.
          +     *  Length definition is consitent, underlying 
          +     *  media def is accessible etc. */
          +    bool
          +    Clip::isValid ()  const
          +    {
          +      UNIMPLEMENTED ("check consistency of clip length def, implies accessing the underlying media def");
          +    }
          +    
          +    
               void 
               Clip::setupLength()
               {
          diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp
          index fb0d00b9a..1a39cb14f 100644
          --- a/src/proc/mobject/session/clip.hpp
          +++ b/src/proc/mobject/session/clip.hpp
          @@ -33,6 +33,7 @@ namespace mobject
             {
             namespace session
               {
          +    using asset::Media;
           
           
               /**
          @@ -63,6 +64,16 @@ namespace mobject
                   
                   virtual void setupLength();
                   
          +      public:
          +        virtual bool isValid()  const;
          +        
          +        /** access the underlying media asset */
          +        virtual Media::PMedia getMedia ()                        
          +          { 
          +            UNIMPLEMENTED ("how to relate MObjects and media assets...");
          +            return AssetManager::instance().getAsset(IDA(0)); // KABOOM! (just to make it compile)
          +          }
          +        
                 };
                 
           
          diff --git a/src/proc/mobject/session/locatingpin.cpp b/src/proc/mobject/session/locatingpin.cpp
          index a054b1736..1404853ee 100644
          --- a/src/proc/mobject/session/locatingpin.cpp
          +++ b/src/proc/mobject/session/locatingpin.cpp
          @@ -101,6 +101,14 @@ namespace mobject
                 return FixedLocation (solution.getTime(), solution.getTrack());
               }
               
          +    bool 
          +    LocatingPin::isOverdetermined () const
          +    {
          +      LocatingSolution solution;
          +      resolve (solution);
          +      return solution.is_impossible(); 
          +    }
          +
               
               inline bool
               still_to_solve (LocatingPin::LocatingSolution& solution) 
          diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp
          index 8f030fff3..431ef5ef3 100644
          --- a/src/proc/mobject/session/locatingpin.hpp
          +++ b/src/proc/mobject/session/locatingpin.hpp
          @@ -51,7 +51,7 @@ using boost::scoped_ptr;
           
           namespace mobject
             {
          -  class Placement;
          +  template class Placement;
           
             namespace session
               {
          @@ -89,10 +89,11 @@ namespace mobject
                   
                 public:
                   const FixedLocation resolve ()  const;
          +        bool isOverdetermined () const;
                   
                   /* Factory functions for adding LocatingPins */
                   
          -        FixedLocation&    operator() (Time, Track);
          +        FixedLocation&    operator() (Time, Track=0);
                   RelativeLocation& operator() (PMO refObj, Time offset=0);
                   
                   LocatingPin (const LocatingPin&);
          diff --git a/src/proc/mobject/session/mobjectfactory.cpp b/src/proc/mobject/session/mobjectfactory.cpp
          index b407f908e..740852558 100644
          --- a/src/proc/mobject/session/mobjectfactory.cpp
          +++ b/src/proc/mobject/session/mobjectfactory.cpp
          @@ -40,12 +40,14 @@ namespace mobject
                *  into a Placement, which takes ownership. So, when the
                *  render engine gets across this Clip-MO, it is able to
                *  obtain the media information contained in the corresponding
          -     *  asset.
          +     *  media asset. Depending on the mediaDef passed in, the 
          +     *  created Clip could be a compound (multichannel) clip 
          +     *  comprised of several SimpleClip subobjects.
          +     *  @todo implement creation of multichannel CompoundClip
                */
               Placement   
               MObjectFactory::operator() (PClipAsset& mediaDef)
               {
          -      //TODO sholdin't we rather store a ref to the underlying media assset??
                 return Placement (new Clip (mediaDef));
               }
               
          diff --git a/tests/components/proc/asset/makecliptest.cpp b/tests/components/proc/asset/makecliptest.cpp
          index 8f8c82192..64497e521 100644
          --- a/tests/components/proc/asset/makecliptest.cpp
          +++ b/tests/components/proc/asset/makecliptest.cpp
          @@ -52,14 +52,14 @@ namespace asset
               class MakeClip_test : public Test
                 {
                   typedef shared_ptr PM;
          -        typedef shared_ptr PC;
          +        typedef asset::Media::PClipMO PC;
                       
                   virtual void run (Arg arg) 
                     {
                       
                       PM mm = asset::Media::create("test-1", VIDEO);
                       PC cc = mm->createClip();
          -            PM cm = static_pointer_cast (cc->getMedia());   //TODO: solve the reference/interface Problem on MObject, push down to Clip...
          +            PM cm = cc->getMedia();
                       
                       ASSERT (cm);
                       ASSERT (0 < cc->getLength());
          diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp
          index 75b87f269..e720535f5 100644
          --- a/tests/components/proc/mobject/placementbasictest.cpp
          +++ b/tests/components/proc/mobject/placementbasictest.cpp
          @@ -66,24 +66,23 @@ namespace mobject
                         PM media = asset::Media::create("test-1", VIDEO);
                         Placement pc = MObject::create(media);
           
          -              // can use the Clip-MObject interface by dereferencing the placement
          +              // use of the Clip-MObject interface by dereferencing the placement
                         PM clip_media = pc->getMedia();
                         ASSERT (clip_media->ident.category.hasKind (VIDEO));
                         
                         // using the Placement interface
                         // TODO: how to handle unterdetermined Placement? Throw?
          -              FixedPlacement & fixpla = pc.chain(Placement::FIXED, Time(1)); // TODO: the track??
          +              FixedLocation & fixloc = pc.chain(Placement::FIXED, Time(1)); // TODO: the track??
                         ExplicitPlacement expla = pc.resolve();
                         ASSERT (expla.time == 1);
          -              ASSERT (!expla.isOverdetermined());
          +              ASSERT (!expla.chain.isOverdetermined());
                         ASSERT (*expla == *pc);
          -              ASSERT (*fixpla == *pc);
                         
                         // now overconstraining with another Placement
                         pc.chain(Placement::FIXED, Time(2));
                         expla = pc.resolve();
                         ASSERT (expla.time == 2); // the latest addition wins
          -              ASSERT (expla.isOverdetermined()); 
          +              ASSERT (expla.chain.isOverdetermined()); 
                       } 
                   };
                 
          
          From 89e4fa9db7f00c1a32c608807febf2dd0fb5b6a4 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Mon, 12 Nov 2007 02:05:39 +0100
          Subject: [PATCH 12/22] WIP getting the placement part through the compiler,
           still having to solve problems with the asset-to-MObject relation
          
          ---
           src/common/time.cpp                           |  6 ++
           src/common/time.hpp                           | 12 ++-
           src/common/util.hpp                           |  2 +-
           src/proc/asset/category.hpp                   |  1 +
           src/proc/asset/clip.cpp                       | 55 ++++++++++--
           src/proc/asset/clip.hpp                       | 11 ++-
           src/proc/asset/media.cpp                      |  2 +-
           src/proc/asset/media.hpp                      |  6 +-
           src/proc/mobject/explicitplacement.hpp        | 10 ++-
           src/proc/mobject/mobject.cpp                  |  2 +-
           src/proc/mobject/mobject.hpp                  |  4 +-
           src/proc/mobject/placement.hpp                | 86 ++++---------------
           src/proc/mobject/session.hpp                  |  6 +-
           src/proc/mobject/session/abstractmo.hpp       | 13 +--
           src/proc/mobject/session/allocation.hpp       |  2 +-
           src/proc/mobject/session/clip.cpp             |  2 +-
           src/proc/mobject/session/clip.hpp             | 38 ++++++--
           src/proc/mobject/session/edl.cpp              |  4 +-
           src/proc/mobject/session/edl.hpp              |  4 +-
           src/proc/mobject/session/effect.hpp           | 17 ++++
           src/proc/mobject/session/fixedlocation.cpp    | 12 +--
           src/proc/mobject/session/fixedlocation.hpp    |  3 +-
           src/proc/mobject/session/locatingpin.cpp      | 49 +++++------
           src/proc/mobject/session/locatingpin.hpp      | 27 ++++--
           src/proc/mobject/session/meta.hpp             | 17 ++++
           src/proc/mobject/session/mobjectfactory.cpp   |  2 +-
           src/proc/mobject/session/mobjectfactory.hpp   | 12 ++-
           src/proc/mobject/session/relativelocation.cpp |  4 +-
           src/proc/mobject/session/relativelocation.hpp |  9 +-
           src/proc/mobject/session/sessionimpl.cpp      |  4 +-
           src/proc/mobject/session/sessionimpl.hpp      |  4 +-
           31 files changed, 261 insertions(+), 165 deletions(-)
          
          diff --git a/src/common/time.cpp b/src/common/time.cpp
          index 9161140e2..a81466ab7 100644
          --- a/src/common/time.cpp
          +++ b/src/common/time.cpp
          @@ -22,10 +22,16 @@
           
           
           #include "common/time.hpp"
          +#include 
          +
           
           namespace cinelerra
             {
           
          +   // TODO: dummy values; should be adjusted when switching to the real time implementation provided by the backend
          +  
          +   const Time Time::MAX = std::numeric_limits::max();
          +   const Time Time::MIN = -MAX;
           
           
           } // namespace cinelerra
          diff --git a/src/common/time.hpp b/src/common/time.hpp
          index 1e94effb7..482f074c9 100644
          --- a/src/common/time.hpp
          +++ b/src/common/time.hpp
          @@ -24,6 +24,7 @@
           #ifndef CINELERRA_TIME_H
           #define CINELERRA_TIME_H
           
          +#include 
           
           
           namespace cinelerra
          @@ -38,13 +39,22 @@ namespace cinelerra
              *       elaborate timehandling functions in the backend and the goal
              *       is for class Time to be just a thin wrapper!
              */
          -  class Time
          +  class Time : boost::totally_ordered
          -
          -
          As always, the main goal is //to cut down complexity// by the usual approach to separate into small manageable chunks.
          +
          +
          This __proc-Layer__ and ~Render-Engine implementation started out as a design-draft by [[Ichthyo|mailto:Ichthyostega@web.de]] in summer 2007. The key idea of this design-draft is to use the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]] for the Render Engine, thus separating completely the //building// of the Render Pipeline from //running,// i.e. doing the actual Render. The Nodes in this Pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder.
          +
          +!Why doesn't the current Cinelerra-2 Design succeed?
          +The design of Cinelerra-2 basically follows a similar design, but __fails because of two reasons__
          +# too much differentiation is put into the class hierarchy instead of configuring Instances differently.<br>This causes overly heavy use of virtual functions and -- in order to ameliorate this -- falling back to hard wired branching
          +# far too much coupling and back-coupling to the internals of the EDL, forcing a overly rigid structure on the latter
          +
          +!Try to learn from this
          +* build up an [[Node Abstraction|ProcNode]] powerful enough to express //all necessary Operations// without the need to recure on the actual object type
          +* need to redesign the internals of the EDL in a far more open manner. See MObjects
          +* strive at a StrongSeparation between EDL and Render Engine
          +
          +
          +!Design Goals
          +As always, the main goal is //to cut down complexity// by the usual approach to separate into small manageable chunks.
           
           To achieve this, here we try to separate ''Configuration'' from ''Processing''. Further, in Configuration we try to separate the ''high level view'' (users view when editing) from the ''low level view'' (the actual configuration effective for the calculations). Finally, we try to factor out and encapsulate ''State'' in order to make State explicit.
           
          -The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in this Pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the automation data, separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes using the same automation data).
          +The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the automation data, separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes using the same automation data).
           
           Another pertinent theme is to make the basic building blocks simpler, while on the other hand gaining much more flexibility for combining these building blocks. For example we try to unfold any "internal-multi" effects into separate instances (e.g. the possibility of having an arbitrary number of single masks at any point of the pipeline instead of having one special masking facility encompassing multiple sub-masks. Similarly, we treat the Objects in the EDL in a more uniform manner and gain the possibility to [[place|Placement]] them in various ways.
           
          @@ -1520,18 +1534,18 @@ 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 whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
          -
          -
          The Cinelerra-3 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 [[EDL]], edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the "bookkeeping view" of all the different "things" within each Session.
          +
          +
          The Cinelerra-3 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 [[EDL]], edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the "bookkeeping view" of all the different "things" within each [[Session|SessionOverview]].
           [img[Block Diagram|uml/fig128005.png]]
           
          -
          +
          Render Engine, [[Builder]] and [[Controller]] are closely related Subsystems. Actually, the [[Builder]] //creates// a newly configured Render Engine //for every// RenderProcess. Before doing so, it queries from the Session (or, to be more precise, from the [[Fixture]] within the current Session) all necessary Media Object Placement information. The [[Builder]] then derives from this information the actual assembly of [[Processing Nodes|ProcNode]] comprising the Render Engine. Thus:
            * the source of the build process is a sequence of absolute (explicit) [[Placements|Placement]] called the [[Playlist]]
            * the [[build process|BuildProcess]] is driven, configured and controlled by the [[Controller]] subsystem component. It encompasses the actual playback configuration and State of the System.
            * the resulting Render Engine is a list of [[Processors]], each configured to calculate a segment of the timeline with uniform properties. Each of these Processors in turn is a graph of interconnected ProcNode.s.
           
          -see also: RenderEntities
          +see also: RenderEntities, [[two Examples (Object diagrams)|Examples]] 
           
           [img[Overview: Components of the Renderengine|uml/fig128261.png]]
           
          @@ -2419,21 +2433,18 @@ The link between ~MObject and Asset should be {{{const}}}, so the clip can't cha At first sight the link between asset and clip-MO is a simple logical relation between entities, but it is not strictly 1:1 because typical media are [[multichannel|MultichannelMedia]]. Even if the media is compound, there is //only one asset::Clip//, because in the logical view we have only one "clip-thing". On the other hand, in the Session/EDL, we have a compound clip ~MObject comprised of several elementary clip objects, each of which will refer to its own sub-media (channel) within the compound media (and don't forget, this structure can be tree-like) {{red{open question:}}} do the clip-MO's of the individual channels refer directly to asset::Media? does this mean the relation is different from the top level, where we have a relation to a asset::Clip??
          -
          -
          The Render Engine is the part of the application doing the actual video calculations. Its operations are guided by the Objects and Parameters edited by the user in [[the EDL|EDL]] and it retrieves the raw audio and video data from the [[Data backend|backend.html]]. Because the inner workings of the Render Engine are closely related to the structures used in the EDL, this design covers [[this aspect|MObjects]] as well.
          +
          +
          The Render Engine is the part of the application doing the actual video calculations. Its operations are guided by the Objects and Parameters edited by the user in [[the EDL|EDL]] and it retrieves the raw audio and video data from the [[Data backend|backend.html]]. Because the inner workings of the Render Engine are closely related to the structures used in the EDL, this design covers [[the aspect of objects placed into the EDL|MObjects]] as well.
          +<<<
          +''Status'': started out as design draft in summer '07, Ichthyo is now in the middle of a //first, draft, prototypical// implementation in C++
          +<<<
           
          -The key idea of Ichthyo's Design-draft is to use the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]] for the Render Engine, thus separating completely the //building// of the Render Pipeline from //running,// i.e. doing the actual Render. The Nodes in this Pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder.
          -([[more on the Design Goals|DesignGoals]])
          +!Summary
          +We have several kinds of "things" organized as [[assets|Asset]] in the AssetManager, like media, clips, effects, codecs, configuration templates. Within the context of the [[EDL]], we can use these as [["Media Objects"|MObjects]] &mdash; especially, we can [[place|Placement]] them in various kinds within the EDL and relative to one another. Basically, this is the [[editing work|EditingOperations]] done by the user.
           
          -!Why doesn't the current Design succeed with this?
          -The design of Cinelerra 2 basically follows this design, but __fails because of two reasons__
          -# too much differentiation is put into the class hierarchy instead of configuring Instances differently.<br>This causes overly heavy use of virtual functions and -- in order to ameliorate this -- falling back to hard wired branching
          -# far too much back-coupling to the internals of the [[EDL]], forcing a overly rigid structure on the latter
          +Now, from any given configuration within the EDL, we create sort or a frozen- and tied-down snapshot, here called [["Fixture"|Fixture]], containing all currently active ~MObjects, broken down to elementary parts and made explicit if necessary. This Fixture acts as a isolation layer towards the Render Engine. We will hand it over to the  [[Builder]], which in turn will transform it into a network of connected [[render nodes|ProcNode]]. This network //is// the [[Render Engine|OverviewRenderEngine]].
           
          -!Try to learn from this
          -* build up an [[Node Abstraction|ProcNode]] powerful enough to express //all necessary Operations// without the need to recure on the actual object type
          -* need to redesign the internals of the EDL in a far more open manner. See MObjects
          -* strive at a StrongSeparation between EDL and Render Engine
          +The system is ''open'' inasmuch every part mirrors the structure of corresponding parts in adjacent subsystems, and the transformation of any given structure from one subsystem (e.g. Asset) to another (e.g. Render Engine) is done with minimal "magic". So the whole system should be able to handle completely new structures mostly by adding new configurations and components, without much need of rewriting basic workings.
           
           !!see also
           &rarr; [[Overview]] of Subsystems and Components, and DesignGoals
          @@ -2879,7 +2890,7 @@ function addKeyDownHandlers(e)
           
           
          -
          +
          The Intention of this text is to help you understanding the design and to show some notable details.
           
           !!!!Starting Point
          @@ -2910,7 +2921,7 @@ An important goal of this approach is to be able to push down the treatment of v
           In case it's not already clear: we don't have "the" Render Engine, rather we construct a Render Engine for each structurally differing part of the timeline. (please relate this to the current Cinelerra code base, which constructs and builds up the render pipeline for each frame separately). No need to call back from within the pipeline to find out if a given plugin is enabled or to see if there are any automation keyframes. We don't need to pose any constraints on the structuring of the objects in the EDL, besides the requirement to get an ExplicitPlacement for each. We could even loosen the use of the common metaphor of placing media sequences on fixed tracks, if we want to get at a more advanced GUI at some point in the future.
           
           !!!!Stateless Subsystems
          -The &raquo;current setup&laquo; of the objects in the EDL is sort of a global state. Same holds true for the Controller, as the Engine can be at playback, it can run a background render or scrub single frames. But the whole complicated subsystem of the Builder and one given Render Engine configuration can be made ''stateless''. As a benefit of this we can run this subsystems multi-threaded without the need of any precautions (locking, synchronizing). Because all state information is just passed in as function parameters and lives in local variables on the stack, or is contained in the StateProxy which represents the given render //process// and is passed down as function parameter as well. (note: I use this term 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).
          +The &raquo;current setup&laquo; of the objects in the EDL is sort of a global state. Same holds true for the Controller, as the Engine can be at playback, it can run a background render or scrub single frames. But the whole complicated subsystem of the Builder and one given Render Engine configuration can be made ''stateless''. As a benefit of this we can run this subsystems multi-threaded without the need of any precautions (locking, synchronizing). Because all state information is just passed in as function parameters and lives in local variables on the stack, or is contained in the StateProxy which represents the given render //process// and is passed down as function parameter as well. (note: I use the term "stateless" in the usual, slightly relaxed manner; of course there are some configuration values contained in instance variables of the objects carrying out the calculations, but this values are considered to be constant over the course of the object usage).
           
          From ce51909ef78778acef3c5dab88b7dcc1a8c46734 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 13 Nov 2007 03:37:58 +0100 Subject: [PATCH 14/22] WIP reworked approach for clip-to-clipAsset relation. (compiler errors spotted a design problem) --- src/proc/asset/clip.cpp | 6 +-- src/proc/mobject/placement.cpp | 41 +++++++++++++++++++++ src/proc/mobject/session/clip.cpp | 18 ++++++++- src/proc/mobject/session/clip.hpp | 11 ++---- src/proc/mobject/session/mobjectfactory.cpp | 6 +-- wiki/renderengine.html | 18 ++++----- 6 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 src/proc/mobject/placement.cpp diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp index 72d2605ba..23e8c0be7 100644 --- a/src/proc/asset/clip.cpp +++ b/src/proc/asset/clip.cpp @@ -51,7 +51,7 @@ namespace asset { return mobject::MObject::create( AssetManager::instance() - .getAsset (mediaID)); + .getAsset (mediaID)); //////TODO: to service the new session::Clip ctor, somehow have to solve the "shared ptr from this" problem } } @@ -77,9 +77,7 @@ namespace asset Clip::createClip () { if (!clipMO_) - clipMO_ = mobject::MObject::create( - AssetManager::instance() - .getAsset (this->getID())); + clipMO_ = createClipMO (this->getID()); return clipMO_; } diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp new file mode 100644 index 000000000..799b7de11 --- /dev/null +++ b/src/proc/mobject/placement.cpp @@ -0,0 +1,41 @@ +/* + Placement - Key Abstraction: a way to place and locate a Media Object + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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/placement.hpp" +#include "proc/mobject/explicitplacement.hpp" + +namespace mobject + { + + + /** */ + template + ExplicitPlacement + Placement::resolve () const + { + return ExplicitPlacement (*this, chain.resolve()); + } + + + +} // namespace mobject diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp index 499567af5..213c98844 100644 --- a/src/proc/mobject/session/clip.cpp +++ b/src/proc/mobject/session/clip.cpp @@ -22,6 +22,8 @@ #include "proc/mobject/session/clip.hpp" +#include "proc/asset/media.hpp" +#include "proc/asset/clip.hpp" namespace mobject { @@ -31,10 +33,13 @@ namespace mobject /** new clip-MO linked with the given asset::Clip. * Initially, this clip will cover the whole source media length. */ - Clip::Clip (PClipAsset& mediaDef) + Clip::Clip (PMedia& mediaDef, PClipAsset& clipRef) : start_(0), - mediaDef_(mediaDef) + mediaDef_(mediaDef), + clipRef_(clipRef) { + REQUIRE (mediaDef_); + REQUIRE (clipRef_); setupLength(); } @@ -56,6 +61,15 @@ namespace mobject UNIMPLEMENTED ("calculate the length of a clip and set length field"); // will use mediaDef to query media parameters.... } + + + PMedia + Clip::getMedia () const + { + UNIMPLEMENTED ("how to relate MObjects and media assets..."); + return mediaDef_->getMedia(); + } + diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index c58cfac3f..ffa467bf0 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -63,9 +63,10 @@ namespace mobject //TODO: where to put the duration ??? - PClipAsset mediaDef_; + PMedia mediaDef_; + PClipAsset clipRef_; - Clip (PClipAsset& mediaDef); + Clip (PMedia& mediaDef, PClipAsset& clipRef); friend class MObjectFactory; @@ -75,11 +76,7 @@ namespace mobject virtual bool isValid() const; /** access the underlying media asset */ - virtual PMedia getMedia () - { - UNIMPLEMENTED ("how to relate MObjects and media assets..."); - //return AssetManager::instance().getAsset(IDA(0)); // KABOOM! (just to make it compile) - } + virtual PMedia getMedia () const; }; diff --git a/src/proc/mobject/session/mobjectfactory.cpp b/src/proc/mobject/session/mobjectfactory.cpp index 8726a28b3..4f375af87 100644 --- a/src/proc/mobject/session/mobjectfactory.cpp +++ b/src/proc/mobject/session/mobjectfactory.cpp @@ -46,9 +46,9 @@ namespace mobject * @todo implement creation of multichannel CompoundClip */ Placement - MObjectFactory::operator() (PClipAsset& mediaDef) + MObjectFactory::operator() (PMedia& mediaDef, PClipAsset& clipRef) { - return Placement (*new Clip (mediaDef), &deleterFunc); + return Placement (*new Clip (mediaDef,clipRef), &deleterFunc); } @@ -56,7 +56,7 @@ namespace mobject Placement MObjectFactory::operator() (asset::Effect processorDef) { - + UNDEFINED ("fabricate effect-MO"); } diff --git a/wiki/renderengine.html b/wiki/renderengine.html index b69449425..e45fc4aad 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -1411,14 +1411,14 @@ This Design strives to achieve a StrongSeparation between the low-level Structur [[Admin]] <<fullscreen>>
          -
          +
          Problem is: when removing an Asset, all corresponding MObjects need to disappear. This means, besides the obvious ~Ref-Link (MObject referring to an asset) we need backlinks or a sort of registry. And still worse: we need to remove the affected MObject from the object network in the EDL and rebuild the Fixture...
           
           &rarr; for a general design discussion see [[Relation of Clip and Asset|RelationClipAsset]]
           
           As a //first shot// Ichthyo considers the following approach:
           * all references between MObjects and Assets are implemented as __refcounting__ boost::shared_ptr
          -* the opposite direction is also a __strong references__, effectively keeping the clip-MO alive even if it is no longer in use in the session (note this is a cyclic dependency that needs to be actively broken on deletion). This design decision is based on  logical considerations (&rarr; see "deletions, Model-2" [[here|RelationClipAsset]]). The back-link is needed only for clean deletion of Assets and for GUI search functions.
          +* the opposite direction is also a __strong reference__, effectively keeping the clip-MO alive even if it is no longer in use in the session (note this is a cyclic dependency that needs to be actively broken on deletion). This design decision is based on  logical considerations (&rarr; see "deletions, Model-2" [[here|RelationClipAsset]]). This back-link is implemented by a Placement which is stored internally within the asset::Clip, it is needed for clean deletion of Assets, for GUI search functions and for adding the Clip to the EDL (again after been removed, or multiple times as if cloned).
           * MObjects and Assets implement an {{{unlink()}}} function releasing the internal links to other entities.
           * Instead of a delete, we call this unlink() function and let the shared_ptr handle the actual deletion.
           * we don't use a registry, rather we model the real dependencies by individual dependency links. So a MediaAsset gets links to all Clips created from this Asset and by traversing this tree, we can handle the deletion
          @@ -1494,24 +1494,24 @@ So, when creating a clip out of such a compound media asset, the clip has to be
           * we distinguish elementay (non-compound) Clips from compound clips by concrete subtype. The builder can only handle elementary clips, because he needs to build a separate pipeline for every output channel. So the work of splitting common effect stacks for clips with several channels needs to be done when calculating the Fixture for the current EDL. The Builder expects to be able to build the render nodes corresponding to each entity found in the Fixture one by one.
           * the Builder gets at the ProcPatt (descriptor) of the underlying media for each clip and uses this description as a template to build the render pipeline. That is, the ProcPatt specifies the codec asset and maybe some additional effect assets (deinterlace, scale) necessary for feeding media data corresponding to this clip/media into the render nodes network.
          -
          +
          We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a instance of some general concept (Interface), or if we have a direct collaboration and thus need the Factory to provide a more specific sub-Interface or even a concrete type.
           
           !Object creation use cases
           !![[Assets|Asset]]
           |!Action|>|!creates |
           |loading a media file|asset::Media, asset::Codec| |
          -|viewing media|asset::Clip| for the whole Media, if not already existent|
          -|mark selection as clip|asset::Clip| doesn't add to EDL|
          +|viewing media|asset::Clip, session::Clip and Placement (on hold)| for the whole Media, if not already existent|
          +|mark selection as clip|asset::Clip, session::Clip, Placement with unspec. LocatingPin| doesn't add to EDL|
           |loading Plugin|asset::Effect| usually at program startup|
           |create Session|asset::Track, asset::OutPort| |
           &rarr; [[Creating and registering Assets|AssetCreation]]
           
           !![[MObjects|MObject]]
          -|add media to EDL|asset::Clip, session::Clip, FixedPlacement| creating whole-media clip on-the-fly |
          -|add Clip|session::Clip, FixedPlacement| |
          -|attach Effect|session::Effect, RelativePlacement| |
          -|start using Automation|session::Auto, asset::Dataset, RelativePlacement| |
          +|add media to EDL|asset::Clip, session::Clip, Placement with unspecified LocatingPin| creating whole-media clip on-the-fly |
          +|add Clip to EDL|copy of Placement| creates intependent Placement of existing ~Clip-MO|
          +|attach Effect|session::Effect, Placement with RelativeLocation| |
          +|start using Automation|session::Auto, asset::Dataset, RelativeLocation Placement| |
           
           !Invariants
           when creating Objects, certain invariants have to be maintained. Because creating an Object can be considered an atomic operation and must not leave any related objects in an inconsistent state. Each of our interfaces implies some invariants:
          
          From b07d8b968789896092a5c16d3e76aea40602d5e0 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Wed, 14 Nov 2007 10:10:52 +0100
          Subject: [PATCH 15/22] passes the compiler again. (using direct references
           instead of smart-ptrs for the 'backlink' from Clip-MO to asset::Media)
          
          ---
           src/common/time.cpp                           |  4 +-
           src/proc/asset/clip.cpp                       | 52 ++++++++++++-------
           src/proc/asset/clip.hpp                       |  4 +-
           src/proc/asset/compoundmedia.hpp              |  2 +-
           src/proc/asset/media.cpp                      | 31 ++++++-----
           src/proc/asset/media.hpp                      |  3 +-
           src/proc/assetmanager.cpp                     | 28 ++++++++--
           src/proc/assetmanager.hpp                     |  3 ++
           src/proc/mobject/explicitplacement.hpp        |  4 ++
           src/proc/mobject/mobject.hpp                  |  1 +
           src/proc/mobject/placement.cpp                | 12 +++--
           src/proc/mobject/placement.hpp                |  3 +-
           src/proc/mobject/session/clip.cpp             | 10 ++--
           src/proc/mobject/session/clip.hpp             | 14 +++--
           src/proc/mobject/session/mobjectfactory.cpp   | 21 +++++---
           src/proc/mobject/session/mobjectfactory.hpp   |  6 ++-
           .../proc/mobject/placementbasictest.cpp       | 20 ++++---
           .../proc/mobject/session/addcliptest.cpp      |  5 +-
           .../proc/mobject/session/deletecliptest.cpp   | 29 +++++++----
           .../mobject/session/rebuildfixturetest.cpp    |  9 ++--
           .../proc/mobject/session/testclip.cpp         | 51 +++++++++++++-----
           .../proc/mobject/session/testclip.hpp         | 39 ++++++++------
           22 files changed, 233 insertions(+), 118 deletions(-)
          
          diff --git a/src/common/time.cpp b/src/common/time.cpp
          index a81466ab7..c257070b7 100644
          --- a/src/common/time.cpp
          +++ b/src/common/time.cpp
          @@ -30,8 +30,8 @@ namespace cinelerra
           
              // TODO: dummy values; should be adjusted when switching to the real time implementation provided by the backend
             
          -   const Time Time::MAX = std::numeric_limits::max();
          -   const Time Time::MIN = -MAX;
          +   const Time Time::MAX = +std::numeric_limits::max();
          +   const Time Time::MIN = -std::numeric_limits::max();
           
           
           } // namespace cinelerra
          diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp
          index 23e8c0be7..9ae562bc8 100644
          --- a/src/proc/asset/clip.cpp
          +++ b/src/proc/asset/clip.cpp
          @@ -22,6 +22,10 @@
           
           
           #include "proc/asset/clip.hpp"
          +#include "proc/mobject/session/mobjectfactory.hpp"   ////TODO: avoidable?
          +
          +using std::tr1::static_pointer_cast;
          +
           
           namespace asset
             {
          @@ -47,11 +51,9 @@ namespace asset
                   }
                 
                 Media::PClipMO
          -      createClipMO (const ID& mediaID)
          +      createClipMO (const Clip& thisClipAsset, const Media& mediaChannel)
                   {
          -          return mobject::MObject::create(
          -                     AssetManager::instance()
          -                               .getAsset (mediaID));  //////TODO: to service the new session::Clip ctor, somehow have to solve the "shared ptr from this" problem
          +          return mobject::MObject::create (thisClipAsset,mediaChannel);
                   }
               }
             
          @@ -61,27 +63,42 @@ namespace asset
               : Media (createClipIdent (mediaref),
                        mediaref.getFilename())
               , source_ (mediaref) 
          -    , clipMO_ (createClipMO (this->getID()))
          +    , clipMO_ (createClipMO (*this, source_))
             {
               
             }
             
             
          -  /** Directly object creating specialisation of the 
          -   *  asset::Media interface method: immediately starting
          -   *  out from this asset::Clip and doing the actual 
          -   *  MObject-creation in case there isn't already 
          -   *  a clip-MO linked with this Clip Asset. 
          +  /** Specialisation of the asset::Media interface method,
          +   *  just returning the already existing Clip-MO. Every
          +   *  asset::Clip internally holds a Clip-MO, which has 
          +   *  been created alongside. This Clip-MO may have several
          +   *  Placements or no placement at all (meaning it need not
          +   *  be placed within the EDL) 
              */
             Media::PClipMO 
          -  Clip::createClip ()
          +  Clip::createClip ()  const
             {
          -    if (!clipMO_)
          -      clipMO_ = createClipMO (this->getID());
          -    
               return clipMO_;
             }
             
          +
          +
          +  /** in spite of asset::Clip being a concrete subclass (and not an asset subinterface),
          +   *  we need to create the following explicit specialisation for asset::Clip#getClipAsset.
          +   *  Basically, it's a "shared-ptr-from-this"-function.
          +   */
          +  template<>
          +  shared_ptr
          +  AssetManager::getPtr (const Clip& asset)
          +  {
          +    ENSURE (instance().known(asset.id), 
          +            "unregistered asset instance encountered.");
          +    return static_pointer_cast
          +            (instance().getAsset (asset.id));
          +    
          +  }
          +
             
             /** return this wrapped into a shared ptr,
              *   because it's already the desired asset::Clip
          @@ -89,10 +106,10 @@ namespace asset
             Media::PClip
             Clip::getClipAsset ()
             {
          -    return PClip (AssetManager::instance()
          -                    .getAsset (this->getID()));
          +    return AssetManager::getPtr(*this);
             }
             
          +
             
             /** specialisation delegating the decision to
              *  the media asset referred by this clip
          @@ -100,10 +117,9 @@ namespace asset
             Media::PMedia
             Clip::checkCompound ()
             {
          -    return source_.checkCompound();
          +    return source_.checkCompound();       ////////////////////////TODO better interface!!!
             }
           
           
           
          -
           } // namespace asset
          diff --git a/src/proc/asset/clip.hpp b/src/proc/asset/clip.hpp
          index 0e01fdb63..80392f290 100644
          --- a/src/proc/asset/clip.hpp
          +++ b/src/proc/asset/clip.hpp
          @@ -43,14 +43,14 @@ namespace asset
                 PClipMO clipMO_;
                 
               public:
          -      virtual PClipMO createClip ();
          -      virtual PMedia checkCompound ();
          +      virtual PClipMO createClip ()  const;
                 
               protected:
                 Clip (const Media& mediaref);
                 friend class MediaFactory;
                 
                 virtual PClip getClipAsset ();
          +      virtual PMedia checkCompound ();
           
               };
               
          diff --git a/src/proc/asset/compoundmedia.hpp b/src/proc/asset/compoundmedia.hpp
          index 62e4f4de0..9e2b64d7e 100644
          --- a/src/proc/asset/compoundmedia.hpp
          +++ b/src/proc/asset/compoundmedia.hpp
          @@ -44,7 +44,7 @@ namespace asset
               {
               protected:
                 /** elementary media assets comprising this compound */
          -      vector tracks;
          +      vector tracks;  // TODO: shouldn't we use shared_ptr here???
           
               };
               
          diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp
          index d4a4bb00f..9aa09225f 100644
          --- a/src/proc/asset/media.cpp
          +++ b/src/proc/asset/media.cpp
          @@ -31,12 +31,16 @@
           #include "nobugcfg.h"
           
           #include 
          +#include 
          +
           
           using util::isnil;
           
          +using boost::format;
           using boost::regex;
           using boost::smatch;
           using boost::regex_search;
          +using std::tr1::dynamic_pointer_cast;
           
           
           namespace asset
          @@ -71,7 +75,7 @@ namespace asset
               PClipMO clipMO = clipAsset->createClip();
               
               ENSURE (clipMO->isValid());
          -    return clip;
          +    return clipMO;
             }
             
             
          @@ -82,7 +86,7 @@ namespace asset
             Media::PClip
             Media::getClipAsset ()
             {
          -    if (PMedia parent = this.checkCompound())
          +    if (PMedia parent = this->checkCompound())
                 return parent->getClipAsset();
               else
                 return Media::create(*this);
          @@ -92,10 +96,10 @@ namespace asset
             Media::PMedia
             Media::checkCompound()  const
             {
          -    PAsset parents = this.getParents();
          -    PMedia parent(0);
          +    vector parents = this->getParents();
          +    PMedia parent;
               if ( !isnil (parents))  // primary parent is a media asset?
          -       parent = dynamic_pointer_cast (parents[0]);
          +       parent = dynamic_pointer_cast (parents[0]);
               return parent;
             }
             
          @@ -204,18 +208,19 @@ namespace asset
              *  @throw Invalid if the given media asset is not top-level,
              *         but rather part or a multichannel (compound) media
              */
          -  shared_ptr&
          +  shared_ptr
             MediaFactory::operator() (const asset::Media& mediaref)  throw(cinelerra::error::Invalid)
             {
               if (mediaref.checkCompound())
          -      throw cinelerra::error::Invalid (CINELERRA_ERROR_PART_OF_COMPOUND, 
          -                                         format("Attempt to create a asset::Clip from the media %s, "
          -                                                "which is not toplevel but rather part or a compound "
          -                                                "(multichannel) media. Found parent Media %s.") 
          -                                                % mediaref 
          -                                                % string(mediaref.checkCompound()));
          +      throw cinelerra::error::Invalid (str(format("Attempt to create a asset::Clip from the media %s, "
          +                                                  "which is not toplevel but rather part or a compound "
          +                                                  "(multichannel) media. Found parent Media %s.") 
          +                                                  % string(mediaref) 
          +                                                  % string(*mediaref.checkCompound()))
          +                                      ,CINELERRA_ERROR_PART_OF_COMPOUND
          +                                      );
               asset::Clip* pC = new asset::Clip (mediaref);
          -    return AssetManager::instance().getAsset (pC->getID());
          +    return AssetManager::instance().getPtr (*pC);
             }
             
             CINELERRA_ERROR_DEFINE (PART_OF_COMPOUND, "part of compound used as toplevel element");
          diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp
          index e60b8274b..4d066b5c3 100644
          --- a/src/proc/asset/media.hpp
          +++ b/src/proc/asset/media.hpp
          @@ -112,6 +112,7 @@ namespace asset
                  *  @return pointer to parent, or \code null
                  */
                 virtual PMedia checkCompound ()  const;
          +      friend class asset::Clip;    ////////////////////////TODO better interface!!!
           
               };
               
          @@ -141,7 +142,7 @@ namespace asset
                 PType operator() (const char* file, const Category& cat);
                 PType operator() (const char* file, asset::Kind);
                 
          -      shared_ptr&
          +      shared_ptr
                 operator() (const asset::Media& mediaref)  throw(cinelerra::error::Invalid);
           
               };
          diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp
          index 508962e94..dfbe7c7ce 100644
          --- a/src/proc/assetmanager.cpp
          +++ b/src/proc/assetmanager.cpp
          @@ -33,6 +33,7 @@
           #include 
           #include 
           
          +using std::tr1::static_pointer_cast;
           using boost::format;
           using boost::bind;
           //using boost::lambda::_1;
          @@ -126,10 +127,9 @@ namespace asset
             }
             
             
          -  /**
          -   * find and return the object registered with the given ID.
          -   * @throws Invalid if nothing is found or if the actual KIND
          -   *         of the stored object differs and can't be casted.  
          +  /** find and return the object registered with the given ID.
          +   *  @throws Invalid if nothing is found or if the actual KIND
          +   *          of the stored object differs and can't be casted.  
              */
             template
             shared_ptr
          @@ -144,6 +144,23 @@ namespace asset
                 else
                   throw UnknownID (id);
             }
          +  
          +  /** convienience shortcut for fetching the registered shared_ptr
          +   *  which is in charge of the given asset instance. By querying
          +   *  directly asset.id (of type ID), the call to registry.get()
          +   *  can bypass the dynamic cast, because the type of the asset 
          +   *  is explicitely given by type KIND. 
          +   */
          +  template
          +  shared_ptr
          +  AssetManager::getPtr (const KIND& asset)
          +  {
          +    ENSURE (instance().known(asset.id), 
          +            "unregistered asset instance encountered.");
          +    return static_pointer_cast
          +            (instance().registry.get (asset.id));
          +  }
          +
           
           
             /**
          @@ -229,4 +246,7 @@ namespace asset
             template shared_ptr AssetManager::getAsset (const ID& id)  throw(cinelerra::error::Invalid);
             template shared_ptr   AssetManager::getAsset (const ID&   id)  throw(cinelerra::error::Invalid);
             
          +  template shared_ptr  AssetManager::getPtr (const Media& asset);
          +
          +  
           } // namespace asset
          diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp
          index abc71445f..a8500ea0b 100644
          --- a/src/proc/assetmanager.hpp
          +++ b/src/proc/assetmanager.hpp
          @@ -71,6 +71,9 @@ namespace asset
                 /** provide the unique ID for given Asset::Ident tuple */
                 static ID getID (const Asset::Ident&);
                 
          +      /** retrieve the registerd shared_ptr for any asset */
          +      template
          +      static shared_ptr getPtr (const KIND& asset);
                 
                 /** find and return corresponging object */
                 template
          diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp
          index 5a86d71ec..1200feef7 100644
          --- a/src/proc/mobject/explicitplacement.hpp
          +++ b/src/proc/mobject/explicitplacement.hpp
          @@ -74,6 +74,10 @@ namespace mobject
                   { };
                   
                 friend ExplicitPlacement Placement::resolve () const;
          +      
          +    private:
          +      /** copying prohibited, ExplicitPlacement is effectively const! */
          +      ExplicitPlacement& operator= (const ExplicitPlacement&);
               };
           
           
          diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp
          index 252d9cf5c..f3b791f53 100644
          --- a/src/proc/mobject/mobject.hpp
          +++ b/src/proc/mobject/mobject.hpp
          @@ -69,6 +69,7 @@ namespace mobject
                 
                 friend class session::MObjectFactory;
                 
          +      
               public:
                 static session::MObjectFactory create;
                 
          diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp
          index 799b7de11..6a6203226 100644
          --- a/src/proc/mobject/placement.cpp
          +++ b/src/proc/mobject/placement.cpp
          @@ -28,10 +28,16 @@ namespace mobject
             {
           
           
          -  /** */
          -  template
          +  /** @note we know we need only this single
          +   *        specialisation, because we define 
          +   *        the Placements of more specific 
          +   *        MObject kinds to be subclasses
          +   *        of Placement, so they
          +   *        will inherit this function.
          +   */
          +  template<>
             ExplicitPlacement
          -  Placement::resolve ()  const 
          +  Placement::resolve ()  const 
               { 
                 return ExplicitPlacement (*this, chain.resolve()); 
               }
          diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp
          index 62fa8e539..1e574580b 100644
          --- a/src/proc/mobject/placement.hpp
          +++ b/src/proc/mobject/placement.hpp
          @@ -101,6 +101,8 @@ namespace mobject
                     return shared_ptr::operator-> (); 
                   }      
                 
          +      virtual ~Placement() {};
          +
                 
                 /** interface for defining the kind of placement
                  *  to employ, and for controling any additional
          @@ -116,7 +118,6 @@ namespace mobject
                 
                 
               protected:
          -      virtual ~Placement() {};
                 Placement (MO & subject, void (*moKiller)(MO*)) 
                   : shared_ptr (&subject, moKiller) {};
                   
          diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp
          index 213c98844..c5cba897c 100644
          --- a/src/proc/mobject/session/clip.cpp
          +++ b/src/proc/mobject/session/clip.cpp
          @@ -22,6 +22,7 @@
           
           
           #include "proc/mobject/session/clip.hpp"
          +#include "proc/assetmanager.hpp"
           #include "proc/asset/media.hpp"
           #include "proc/asset/clip.hpp"
           
          @@ -33,13 +34,11 @@ namespace mobject
               /** new clip-MO linked with the given asset::Clip.
                *  Initially, this clip will cover the whole source media length. 
                */
          -    Clip::Clip (PMedia& mediaDef, PClipAsset& clipRef)
          +    Clip::Clip (const asset::Clip& clipDef, const Media& mediaDef)
                 : start_(0),
                   mediaDef_(mediaDef),
          -        clipRef_(clipRef)
          +        clipDef_(clipDef)
               {
          -      REQUIRE (mediaDef_);
          -      REQUIRE (clipRef_);
                 setupLength();
               }
               
          @@ -66,8 +65,7 @@ namespace mobject
               PMedia 
               Clip::getMedia ()  const                        
               { 
          -      UNIMPLEMENTED ("how to relate MObjects and media assets...");
          -      return mediaDef_->getMedia();
          +      return asset::AssetManager::getPtr (mediaDef_);
               }
           
           
          diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp
          index ffa467bf0..9090e347d 100644
          --- a/src/proc/mobject/session/clip.hpp
          +++ b/src/proc/mobject/session/clip.hpp
          @@ -31,7 +31,6 @@ namespace asset
             {
               class Media;
               class Clip;
          -    typedef shared_ptr PClipAsset;
             }
           
           namespace mobject
          @@ -39,7 +38,6 @@ namespace mobject
             namespace session
               {
               using asset::Media;
          -    using asset::PClipAsset;
               typedef shared_ptr PMedia;
           
           
          @@ -51,8 +49,8 @@ namespace mobject
                * into the ouput. The actual media type of a clip will be derived
                * at runtime by resolving this reference to the underlying Asset.
                * 
          -     * TODO: define how to denote Time positions /lengths. This is tricky,
          -     * because it depends on the actual media type, and we wand to encapsulate
          +     * @todo define how to denote Time positions /lengths. This is tricky,
          +     * because it depends on the actual media type, and we want to encapsulate
                * all these details as much as possible. 
                */
               class Clip : public AbstractMO
          @@ -63,10 +61,10 @@ namespace mobject
           
                   //TODO: where to put the duration ???
                   
          -        PMedia mediaDef_;
          -        PClipAsset clipRef_;
          +        const Media & mediaDef_;
          +        const asset::Clip & clipDef_;
           
          -        Clip (PMedia& mediaDef, PClipAsset& clipRef);
          +        Clip (const asset::Clip&, const Media&);
                   friend class MObjectFactory;
                   
                   
          @@ -76,7 +74,7 @@ namespace mobject
                   virtual bool isValid()  const;
                   
                   /** access the underlying media asset */
          -        virtual PMedia getMedia ()  const;
          +        PMedia getMedia ()  const;
                   
                 };
                 
          diff --git a/src/proc/mobject/session/mobjectfactory.cpp b/src/proc/mobject/session/mobjectfactory.cpp
          index 4f375af87..194d84bf1 100644
          --- a/src/proc/mobject/session/mobjectfactory.cpp
          +++ b/src/proc/mobject/session/mobjectfactory.cpp
          @@ -40,23 +40,32 @@ namespace mobject
                *  into a Placement, which takes ownership. So, when the
                *  render engine gets across this Clip-MO, it is able to
                *  obtain the media information contained in the corresponding
          -     *  media asset. Depending on the mediaDef passed in, the 
          +     *  media asset. Note this will create a single track clip. 
          +     *  @param mediaDef the actual asset::Media to be used 
                *  created Clip could be a compound (multichannel) clip 
                *  comprised of several SimpleClip subobjects.
          -     *  @todo implement creation of multichannel CompoundClip
                */
               Placement   
          -    MObjectFactory::operator() (PMedia& mediaDef, PClipAsset& clipRef)
          +    MObjectFactory::operator() (const asset::Clip& clipRef, const asset::Media& mediaDef)
               {
          -      return Placement (*new Clip (mediaDef,clipRef), &deleterFunc);
          +      return Placement (*new Clip (clipRef,mediaDef), &deleterFunc);
               }
               
          +    /** variant of the Clip-MO factory function, creating
          +     *  a multichannel (compound) clip.
          +     *  @todo work out the details of multichannel handling
          +     */
          +    Placement
          +    MObjectFactory::operator() (const asset::Clip& clipRef, vector mediaTracks)
          +    {
          +      UNIMPLEMENTED ("build multichannel compound clip-MO");
          +    }
               
          -    /** */
          +    /** */ 
               Placement
               MObjectFactory::operator() (asset::Effect processorDef)
               {
          -      UNDEFINED ("fabricate effect-MO");
          +      UNIMPLEMENTED ("fabricate effect-MO");
               }
           
           
          diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp
          index 7d7130b5b..aeb267f3a 100644
          --- a/src/proc/mobject/session/mobjectfactory.hpp
          +++ b/src/proc/mobject/session/mobjectfactory.hpp
          @@ -31,6 +31,7 @@
           namespace asset
             {
             class Clip;
          +  class Media;
             class Effect;
             
             }
          @@ -46,14 +47,15 @@ namespace mobject
           
               class MObjectFactory
                 {
          -        /** custom deleter func allowing class Placement 
          +        /** custom deleter func allowing class Placement    
                     *  to take ownership of MObjct instances
                     */
                   static void deleterFunc (MObject* o) { delete o; }
                   
                 public:
                   
          -        Placement   operator() (PClipAsset&);
          +        Placement   operator() (const asset::Clip&, const asset::Media&);
          +        Placement   operator() (const asset::Clip&, vector);
                   Placement operator() (const asset::Effect);
                   
                 };
          diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp
          index e720535f5..5ec9daa9f 100644
          --- a/tests/components/proc/mobject/placementbasictest.cpp
          +++ b/tests/components/proc/mobject/placementbasictest.cpp
          @@ -22,11 +22,14 @@
           
           
           #include "common/test/run.hpp"
          +#include "proc/asset/media.hpp"
           #include "proc/mobject/session.hpp"
           #include "proc/mobject/session/edl.hpp"
           #include "proc/mobject/session/testclip.hpp"
           #include "proc/mobject/placement.hpp"
          +#include "proc/mobject/explicitplacement.hpp"
           #include "common/util.hpp"
          +#include "proc/mobject/session/mobjectfactory.hpp"   ////TODO: avoidable?
           
           //#include 
           #include 
          @@ -45,6 +48,7 @@ namespace mobject
               namespace test
                 {
                 
          +      using asset::VIDEO;
                 
                 
                 
          @@ -58,13 +62,15 @@ namespace mobject
                 class PlacementBasic_test : public Test
                   {
                     typedef shared_ptr PM;
          +          typedef shared_ptr PCA;
                     
                     virtual void
                     run (Arg arg) 
                       {
                         // create Clip-MObject, which is wrapped into a placement (smart ptr)
                         PM media = asset::Media::create("test-1", VIDEO);
          -              Placement pc = MObject::create(media);
          +              PCA clipAsset = Media::create(*media);
          +              Placement pc = MObject::create (*clipAsset, *media);
           
                         // use of the Clip-MObject interface by dereferencing the placement
                         PM clip_media = pc->getMedia();
          @@ -72,17 +78,17 @@ namespace mobject
                         
                         // using the Placement interface
                         // TODO: how to handle unterdetermined Placement? Throw?
          -              FixedLocation & fixloc = pc.chain(Placement::FIXED, Time(1)); // TODO: the track??
          +              FixedLocation & fixloc = pc.chain(Time(1)); // TODO: the track??
                         ExplicitPlacement expla = pc.resolve();
                         ASSERT (expla.time == 1);
                         ASSERT (!expla.chain.isOverdetermined());
          -              ASSERT (*expla == *pc);
          +              //ASSERT (*expla == *pc);  ////////////////////////TODO: definie equality on placements
                         
                         // now overconstraining with another Placement
          -              pc.chain(Placement::FIXED, Time(2));
          -              expla = pc.resolve();
          -              ASSERT (expla.time == 2); // the latest addition wins
          -              ASSERT (expla.chain.isOverdetermined()); 
          +              pc.chain(Time(2));
          +              ExplicitPlacement expla2 = pc.resolve();
          +              ASSERT (expla2.time == 2); // the latest addition wins
          +              ASSERT (expla2.chain.isOverdetermined()); 
                       } 
                   };
                 
          diff --git a/tests/components/proc/mobject/session/addcliptest.cpp b/tests/components/proc/mobject/session/addcliptest.cpp
          index 65f0b96b1..35cb24f98 100644
          --- a/tests/components/proc/mobject/session/addcliptest.cpp
          +++ b/tests/components/proc/mobject/session/addcliptest.cpp
          @@ -60,10 +60,9 @@ namespace mobject
                       {
                         PSess sess = Session::current;
                         PMO clip = TestClip::create();
          -              PPla pla = Placement::create(Placement::FIXED, Time(1), clip);
          -              sess->add (pla);
          +              sess->add (clip);
                         
          -              ASSERT (sess->currEDL().contains (pla));
          +              ASSERT (sess->currEDL().contains (clip));
                         // TODO: Clip-Asset and Placement magic??
                       } 
                   };
          diff --git a/tests/components/proc/mobject/session/deletecliptest.cpp b/tests/components/proc/mobject/session/deletecliptest.cpp
          index a44942a91..5258e2b61 100644
          --- a/tests/components/proc/mobject/session/deletecliptest.cpp
          +++ b/tests/components/proc/mobject/session/deletecliptest.cpp
          @@ -26,6 +26,7 @@
           #include "proc/mobject/session.hpp"
           #include "proc/mobject/session/edl.hpp"               // TODO: really neded?
           #include "proc/mobject/session/testsession1.hpp"
          +#include "proc/mobject/session/clip.hpp"              // TODO: really neded?
           //#include "common/util.hpp"
           
           //#include 
          @@ -39,6 +40,9 @@ using proc_interface::AssetManager;
           using proc_interface::PAsset;
           using proc_interface::IDA;
           
          +using std::tr1::dynamic_pointer_cast;        /// TODO only temp
          +
          +
           namespace mobject
             {
             namespace session
          @@ -63,16 +67,21 @@ namespace mobject
                         PSess sess = Session::current;
                         AssetManager& aMang = AssetManager::instance();
                         
          -              PPla clipPlacement = sess->currEDL().find(SESSION1_CLIP); // global Var asigned in buildTestsession1()
          -              PAsset clipAsset = clipPlacement->subject->getMedia();
          -              IDA clipAID = clipAsset->getID();
          -              ASSERT (clipPlacement);
          -              
          -              sess->remove (clipPlacement);
          -              
          -              ASSERT (!sess->currEDL().find(SESSION1_CLIP));            // EDL forgot the Clip/Placement
          -              ASSERT (!aMang.known (clipAID));                          // corresponding Clip Asset has disappeared 
          -              ASSERT (!clipPlacement->subject->getMedia());             // internal cross-links removed
          +              UNIMPLEMENTED("typesafe searching for MObjects in the EDL");
          +  
          +///////TODO: work out how to search within EDL!!
          +//              
          +//              PClipMO clipPlacement = sess->currEDL().find(SESSION1_CLIP); 
          +//                                                              // global Var asigned in buildTestsession1()
          +//              PMedia media = clipPlacement->getMedia();
          +//              IDA clipAID = media->getID();
          +//              ASSERT (clipPlacement);
          +//              
          +//              sess->remove (clipPlacement);
          +//              
          +//              ASSERT (!sess->currEDL().find(SESSION1_CLIP));            // EDL forgot the Clip/Placement
          +//              ASSERT (!aMang.known (clipAID));                          // corresponding Clip Asset has disappeared 
          +//              ASSERT (!clipPlacement->getMedia());                      // internal cross-links removed
                       } 
                   };
                 
          diff --git a/tests/components/proc/mobject/session/rebuildfixturetest.cpp b/tests/components/proc/mobject/session/rebuildfixturetest.cpp
          index dc4943595..b92e2288a 100644
          --- a/tests/components/proc/mobject/session/rebuildfixturetest.cpp
          +++ b/tests/components/proc/mobject/session/rebuildfixturetest.cpp
          @@ -77,10 +77,13 @@ namespace mobject
                       } 
                     
                     static void 
          -          check_is_from_EDL (PPla explicitPlacement, EDL& edl)
          +          check_is_from_EDL (PMO explicitPlacement, EDL& edl)
                       {
          -              PPla originalPlacement = explicitPlacement->subject->getPlacement();
          -              ASSERT (edl.contains(originalPlacement));
          +              
          +////TODO do we still support this? can it be replaced by a directly checking predicate on ExplicitPlacement??
          +              
          +//              PMO originalPlacement = explicitPlacement->subject->getPlacement();
          +//              ASSERT (edl.contains(originalPlacement));
                       }
                   };
                 
          diff --git a/tests/components/proc/mobject/session/testclip.cpp b/tests/components/proc/mobject/session/testclip.cpp
          index 0fefffad8..e91ac5ed9 100644
          --- a/tests/components/proc/mobject/session/testclip.cpp
          +++ b/tests/components/proc/mobject/session/testclip.cpp
          @@ -26,6 +26,7 @@
           #include "backend/mediaaccessmock.hpp"
           #include "proc/asset/media.hpp"
           #include "proc/asset/clip.hpp"
          +#include "common/singleton.hpp"
           
           namespace mobject
             {
          @@ -33,31 +34,55 @@ namespace mobject
               {
               namespace test
                 {
          -      typedef shared_ptr PC;
                 typedef shared_ptr PM;
                 typedef backend_interface::MediaAccessFacade MAF;
                 using backend_interface::test::MediaAccessMock;
                 using asset::VIDEO;
          -        
           
          -      /** @todo find a way to link to an existing clip object.
          -       *        Idea: use the clip's copy operation, i.e. feed it
          -       *        to mobject::session::clip copy ctor
          -       */
          -      TestClip::TestClip ()
          +      
          +      
          +      asset::Media & 
          +      createTestMedia ()
                 {
                   // install Mock-Interface to cinelerra backend
                   MAF::instance.injectSubclass (new MediaAccessMock);
          -        
                   PM media = asset::Media::create("test-2", VIDEO); // query magic filename
          -        PC clip = media->createClip();
          -        //TODO how to link to *this ???
          -        
                   MAF::instance.injectSubclass (0); // remove Mock-Interface
          +        
          +        return *media;
          +      }
          +      
          +      asset::Clip & 
          +      createTestClipAsset (asset::Media& media)
          +      {
          +        return *(asset::Media::create(media)); 
          +      }
          +      
          +    
          +      struct Testbed
          +        {
          +          asset::Media & media_;
          +          asset::Clip & clipA_;
          +          
          +          Testbed() 
          +            : media_ (createTestMedia()),
          +              clipA_ (createTestClipAsset(media_))
          +            { }
          +        };
          +          
          +      cinelerra::Singleton testbed_1;
          +
          +      
          +      
          +      
          +
          +      TestClip::TestClip ()
          +        : Clip(testbed_1().clipA_,
          +               testbed_1().media_)
          +      {
          +        ASSERT (isValid());
                 }
                 
          -      /** storage for the TestClip-Factory */
          -      TestClip::Factory TestClip::create;
           
           
               } // namespace test
          diff --git a/tests/components/proc/mobject/session/testclip.hpp b/tests/components/proc/mobject/session/testclip.hpp
          index 39ed7df17..0e60a0ce8 100644
          --- a/tests/components/proc/mobject/session/testclip.hpp
          +++ b/tests/components/proc/mobject/session/testclip.hpp
          @@ -47,33 +47,42 @@ namespace mobject
               {
               namespace test
                 {
          -        
          +      class TestPlacement;
          +       
                 /**
                  * Sample or Test Clip for checking
                  * various EDL, session and builder operations.
          -       * Can be used as Mock object to record invoked operations.
          +       * @todo make this usable as Mock object to record invoked operations.
                  * 
                  */
                 class TestClip   : public mobject::session::Clip   /////////////TODO how this????
                   {
                     
          -          /** smart ptr factory allowed to invoke TestClip's ctor */
          -          struct Factory : cinelerra::Factory
          -            {
          -              typedef shared_ptr PType;
          -              PType operator() () { return PType (new TestClip, &destroy); }
          -            protected:
          -              static void destroy (TestClip* tc) { delete tc; }
          -            };
          -          
          -          
          -          TestClip ();  
          -          friend class Factory;  
          +          TestClip ();
          +          static void deleter (MObject* mo) { delete (TestClip*)mo; }
          +
          +          friend class TestPlacement;  
                     
                   public:
          -          static Factory create;
          +          static Placement create () ;
                   };
          +
                   
          +      class TestPlacement : public Placement
          +        {
          +          
          +        public:
          +          TestPlacement (TestClip & subject)
          +            : Placement (subject, &TestClip::deleter)
          +            { }
          +        };
          +
          +        
          +      inline Placement
          +      TestClip::create()
          +      { 
          +        return TestPlacement (*new TestClip); 
          +      }
               
               
               
          
          From 5dcb9cf343e98303546feed574d85ffd277f6aa3 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Mon, 19 Nov 2007 04:58:18 +0100
          Subject: [PATCH 16/22] WIP implemented basic asset dependencies, > todo:
           actually setup dependencies in the various ctors, fix the broken test!
          
          ---
           src/common/util.hpp               | 12 +++++++
           src/proc/asset.cpp                | 60 ++++++++++++++++++-------------
           src/proc/asset.hpp                | 21 +++++++----
           src/proc/asset/clip.cpp           |  5 +--
           src/proc/asset/media.cpp          | 13 +++++--
           src/proc/asset/media.hpp          | 12 +++++--
           src/proc/asset/preview.cpp        | 48 +++++++++++++++++++++++++
           src/proc/asset/preview.hpp        |  3 +-
           src/proc/asset/unknown.cpp        |  9 ++++-
           src/proc/asset/unknown.hpp        |  2 +-
           src/proc/assetmanager.cpp         |  1 +
           src/proc/mobject/session/clip.cpp |  4 +--
           src/proc/mobject/session/clip.hpp |  2 --
           wiki/renderengine.html            | 10 +++---
           14 files changed, 153 insertions(+), 49 deletions(-)
          
          diff --git a/src/common/util.hpp b/src/common/util.hpp
          index 3d465f666..ea21c2a9c 100644
          --- a/src/common/util.hpp
          +++ b/src/common/util.hpp
          @@ -102,6 +102,18 @@ namespace util
               return end != std::find(cont.begin(),end, val);
             }
             
          +  /** shortcut for removing all copies of an Element
          +   *  in any sequencial collection */
          +  template 
          +  inline typename SEQ::iterator 
          +  removeall (SEQ& coll, typename SEQ::value_type& val)
          +  {
          +    typename SEQ::iterator collEnd = coll.end();
          +    return coll.erase (std::remove (coll.begin(), collEnd, val),
          +                       collEnd
          +                      );
          +  }
          +  
             
             /** shortcut for operating on all elements of a container.
              *  Isn't this already defined somewhere? It's so obvious..
          diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp
          index 4fb8429a8..f9136bb20 100644
          --- a/src/proc/asset.cpp
          +++ b/src/proc/asset.cpp
          @@ -25,10 +25,17 @@
           #include "proc/assetmanager.hpp"
           #include "common/util.hpp"
           
          +#include 
           #include 
          +#include 
           
           
          +using boost::bind;
           using boost::format;
          +using boost::function;
          +using util::contains;
          +using util::removeall;
          +using util::for_each;
           using util::cStr;
           
           
          @@ -70,29 +77,8 @@ namespace asset
             }
           
             
          -  /** List of entities this asset depends on or requires to be functional. 
          -   *  May be empty. The head of this list can be considered the primary prerequisite
          -   */
          -  vector
          -  Asset::getParents ()  const
          -  {
          -    UNIMPLEMENTED ("Asset dependencies.");
          -  }
          -
          -
          -  /** All the other assets requiring this asset to be functional. 
          -   *  For example, all the clips depending on a given media file.
          -   *  May be empty. The dependency relation is transitive.
          -   */
          -  vector
          -  Asset::getDependant ()  const
          -  {
          -    UNIMPLEMENTED ("Asset dependencies.");
          -  }
          -
          -
             /**
          -   * weather this asset is swithced on and consequently included
          +   * whether this asset is swithced on and consequently included
              * in the fixture and participates in rendering.
              */
             bool
          @@ -114,18 +100,44 @@ namespace asset
             }
             
             
          +  
          +  
          +  void
          +  Asset::unregister (PAsset& other)  ///< @internal
          +  {
          +    other->unlink (this->id);  
          +  }
          +    
             /** release all links to other Asset objects held internally. */
             void 
             Asset::unlink ()
             {
          -    UNIMPLEMENTED ("deleting Assets.");
          +    function unregister_me = bind(&Asset::unregister, this,_1);
          +    
          +    for_each (parents, unregister_me);
          +    for_each (dependants, unregister_me);
          +    dependants.clear();
          +    parents.clear();
             }
                 
             /** variant dropping only the links to the given Asset */
             void 
             Asset::unlink (IDA target)
             {
          -    UNIMPLEMENTED ("deleting Assets.");
          +    PAsset asset (AssetManager::instance().getAsset (target));
          +    removeall (dependants,asset);
          +    removeall (parents,asset);
          +  }
          +  
          +  
          +  void 
          +  Asset::defineDependency (PAsset parent)
          +  {
          +    PAsset p_this (AssetManager::getPtr(*this));
          +    REQUIRE (!contains (parent->dependants, p_this));
          +    REQUIRE (!contains (this->parents, parent));
          +    parents.push_back (parent);
          +    parent->dependants.push_back(p_this);
             }
           
             
          diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp
          index a32111bfb..ebac8bd7a 100644
          --- a/src/proc/asset.hpp
          +++ b/src/proc/asset.hpp
          @@ -104,6 +104,7 @@ namespace asset
             class Asset;
             class AssetManager;
             typedef const ID& IDA;
          +  typedef shared_ptr PAsset;
           
             
             
          @@ -210,6 +211,9 @@ namespace asset
                 /** user visible qualification of the thing, unit or concept represented by this asset.
                  *  perferably "in one line". To be localized.  */
                 const string longDesc;
          +      
          +      vector parents;
          +      vector dependants;
           
                 
                 
          @@ -237,7 +241,15 @@ namespace asset
                  *  Asset, leaving all other links intact. Usable for propagating  */
                 virtual void unlink (IDA target);
                 
          +      /** establish a connection between this and the given parent asset,
          +       *  denoting we are in some way dependant on the parent. */
          +      virtual void defineDependency (PAsset parent);
          +      
                 friend class AssetManager;
          +      
          +    private:
          +        void unregister (PAsset& other);
          +
           
           
               
          @@ -245,15 +257,13 @@ namespace asset
                 /** List of entities this asset depends on or requires to be functional. 
                  *  May be empty. The head of this list can be considered the primary prerequisite
                  */
          -      vector >  
          -      getParents ()  const;                 ////////////////TODO: better const vector, and return a ref!
          +      const vector& getParents ()  const { return parents; }
                 
                 /** All the other assets requiring this asset to be functional. 
                  *  For example, all the clips depending on a given media file. 
                  *  May be empty. The dependency relation is transitive.
                  */
          -      vector >
          -      getDependant ()  const;
          +      const vector& getDependant ()  const { return dependants; }
                 
                 /** weather this asset is swithced on and consequently 
                  *  included in the fixture and participates in rendering
          @@ -270,9 +280,6 @@ namespace asset
               };
               
               
          -    /** shorthand for refcounting Asset pointers */
          -    typedef shared_ptr PAsset;
          -    
               /** ordering of Asset smart ptrs based on Ident tuple.
                *  @todo currently supporting only smart_ptr. */
               inline bool operator== (const PAsset& a1, const PAsset& a2) { return a1 && a2 && ( 0==a1->ident.compare(a2->ident));}
          diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp
          index 9ae562bc8..4de320bf4 100644
          --- a/src/proc/asset/clip.cpp
          +++ b/src/proc/asset/clip.cpp
          @@ -34,7 +34,7 @@ namespace asset
               {
                 /** @internal derive a sensible asset ident tuple
                  *  when creating a asset::Clip based on some asset::Media
          -       *  @todo getting this one is important for handling creation
          +       *  @todo getting this one correct is important for handling creation
                  *        of multiple clip instances from one media. Means we
                  *        have still to figure out a sensible concept...
                  */
          @@ -61,7 +61,8 @@ namespace asset
             
             Clip::Clip (const Media& mediaref)
               : Media (createClipIdent (mediaref),
          -             mediaref.getFilename())
          +             mediaref.getFilename(),
          +             mediaref.getLength())
               , source_ (mediaref) 
               , clipMO_ (createClipMO (*this, source_))
             {
          diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp
          index 9aa09225f..6d61d7004 100644
          --- a/src/proc/asset/media.cpp
          +++ b/src/proc/asset/media.cpp
          @@ -105,7 +105,7 @@ namespace asset
             
             
             Media::PProcPatt
          -  Media::howtoProc ()
          +  Media::howtoProc ()  const
             {
               UNIMPLEMENTED ("calculate and return processing pattern for media asset");
               PProcPatt ppatt; //TODO:null
          @@ -115,6 +115,13 @@ namespace asset
             }
             
             
          +  cinelerra::Time
          +  Media::getLength()  const
          +  {
          +     return len_;
          +  }
          +  
          +  
             
             MediaFactory Media::create;  ///< storage for the static MediaFactory instance
             
          @@ -148,8 +155,10 @@ namespace asset
                 {
                   if (isnil (key.name)) key.name=extractName(file);
                   TODO ("file exists?");
          +        TODO ("extract media file properties");
          +        Time length(25);
                   TODO ("detecting and wiring multichannel compound media!");
          -        pM = new Media (key,file); 
          +        pM = new Media (key,file,length); 
                 }
               ASSERT (pM);
               ENSURE (key.category.hasKind (VIDEO) || key.category.hasKind(AUDIO));
          diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp
          index 4d066b5c3..defaf51b2 100644
          --- a/src/proc/asset/media.hpp
          +++ b/src/proc/asset/media.hpp
          @@ -50,6 +50,8 @@ namespace asset
             class MediaFactory;
             class ProcPatt;
             
          +  using cinelerra::Time;
          +  
             
             template<>
             class ID : public ID
          @@ -67,6 +69,7 @@ namespace asset
             class Media : public Asset
               {
                 string filename_;
          +      const Time len_;
                 
               public:
                 typedef shared_ptr PMedia;
          @@ -97,10 +100,15 @@ namespace asset
                  *  necessary for this Media or Clip. This includes
                  *  Codecs and postprocessing (stretching, deinterlacing...)
                  */
          -      PProcPatt howtoProc ();
          +      PProcPatt howtoProc ()  const;
          +      
          +      /** @return the overall length of the media represented by this asset */ 
          +      virtual Time getLength ()  const;
          +      
                 
               protected:
          -      Media (const Asset::Ident& idi, const string& file) : Asset(idi), filename_(file) {}
          +      Media (const Asset::Ident& idi, const string& file, Time length) 
          +        : Asset(idi), filename_(file), len_(length) {}
                 friend class MediaFactory;
                 
                 /** get or create the correct asset::Clip 
          diff --git a/src/proc/asset/preview.cpp b/src/proc/asset/preview.cpp
          index 85dc98596..212e85666 100644
          --- a/src/proc/asset/preview.cpp
          +++ b/src/proc/asset/preview.cpp
          @@ -25,6 +25,54 @@
           
           namespace asset
             {
          +  
          +  
          +  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)
          +        {
          +          string name (mediaref.name + "-proxy");  // TODO something sensible here; append number, sanitize etc.
          +          Category category (mediaref.category);
          +          TODO ("put it in another subfolder within the same category??");
          +          return Asset::Ident (name, category, 
          +                               mediaref.org, 
          +                               mediaref.version );
          +          
          +        }
          +    }
          +  
          +  
          +  
          +  /** create a preview placeholder ("proxy media") for the given
          +   *  media asset 
          +   */
          +  Preview::Preview (const Media& mediaref)
          +    : Media (createProxyIdent (mediaref.ident),
          +             mediaref.getFilename(),
          +             mediaref.getLength())
          +  {
          +    UNIMPLEMENTED ("do something to setup proxy media");
          +  }
          +  
          +  
          +  
          +  /** create a dummy placeholder
          +   *  @internal for use by asset::Unknown
          +   *  @todo better design!
          +   */
          +  Preview::Preview (const Asset::Ident& idi, string name, Time length)
          +    : Media (createProxyIdent (idi),
          +             name, length)
          +  {
          +    TODO ("work out how to handle unknown media placheholder");
          +  }
          +
           
           
           
          diff --git a/src/proc/asset/preview.hpp b/src/proc/asset/preview.hpp
          index 689bdc295..abf3734f3 100644
          --- a/src/proc/asset/preview.hpp
          +++ b/src/proc/asset/preview.hpp
          @@ -37,7 +37,8 @@ namespace asset
             class Preview : public Media
               {
               protected:
          -      Preview (const Asset::Ident& idi) : Media(idi,"") {}
          +      Preview (const Media& mediaref);
          +      Preview (const Asset::Ident& idi, string name, Time length);
                 friend class MediaFactory;
               };
               
          diff --git a/src/proc/asset/unknown.cpp b/src/proc/asset/unknown.cpp
          index 8e4e558cd..357db430b 100644
          --- a/src/proc/asset/unknown.cpp
          +++ b/src/proc/asset/unknown.cpp
          @@ -26,8 +26,15 @@
           namespace asset
             {
             
          -  /** */
             
          +  const cinelerra::Time DUMMY_TIME (25);
          +  
          +  /** */
          +  Unknown::Unknown (const Asset::Ident& idi)
          +    : Preview (idi, "", DUMMY_TIME)
          +  {
          +    TODO ("do something sensible with the »unknown media« placeholder...");
          +  }  
             
             
           } // namespace asset
          diff --git a/src/proc/asset/unknown.hpp b/src/proc/asset/unknown.hpp
          index 189a6438b..85db2ac81 100644
          --- a/src/proc/asset/unknown.hpp
          +++ b/src/proc/asset/unknown.hpp
          @@ -38,7 +38,7 @@ namespace asset
             class Unknown : public Preview
               {
               protected:
          -      Unknown (const Asset::Ident& idi) : Preview(idi) {}
          +      Unknown (const Asset::Ident& idi);
                 friend class MediaFactory;
               };
               
          diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp
          index dfbe7c7ce..5fa4183f2 100644
          --- a/src/proc/assetmanager.cpp
          +++ b/src/proc/assetmanager.cpp
          @@ -246,6 +246,7 @@ namespace asset
             template shared_ptr AssetManager::getAsset (const ID& id)  throw(cinelerra::error::Invalid);
             template shared_ptr   AssetManager::getAsset (const ID&   id)  throw(cinelerra::error::Invalid);
             
          +  template shared_ptr  AssetManager::getPtr (const Asset& asset);
             template shared_ptr  AssetManager::getPtr (const Media& asset);
           
             
          diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp
          index c5cba897c..e5e097073 100644
          --- a/src/proc/mobject/session/clip.cpp
          +++ b/src/proc/mobject/session/clip.cpp
          @@ -57,8 +57,8 @@ namespace mobject
               void 
               Clip::setupLength()
               {
          -      UNIMPLEMENTED ("calculate the length of a clip and set length field");
          -      // will use mediaDef to query media parameters....
          +      TODO ("really calculate the length of a clip and set length field");
          +      this->length = mediaDef_.getLength();
               }
               
               
          diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp
          index 9090e347d..ab25f8a76 100644
          --- a/src/proc/mobject/session/clip.hpp
          +++ b/src/proc/mobject/session/clip.hpp
          @@ -59,8 +59,6 @@ namespace mobject
                   /** startpos in source */
                   Time start_;
           
          -        //TODO: where to put the duration ???
          -        
                   const Media & mediaDef_;
                   const asset::Clip & clipDef_;
           
          diff --git a/wiki/renderengine.html b/wiki/renderengine.html
          index e45fc4aad..83be72225 100644
          --- a/wiki/renderengine.html
          +++ b/wiki/renderengine.html
          @@ -1440,7 +1440,7 @@ As a //first shot// Ichthyo considers the following approach:
           [img[Asset Classess|uml/fig130437.png]]
           
          -
          +
          Of course: Cinelerra currently leaks memory and crashes regularilly. For the newly written code, besides retaining the same performance level, a main goal is to use methods and techniques known to support the writing of quality code. So, besides the MultithreadConsiderations, a solid strategy for managing the ownership of allocated memory blocks is necessary right from start.
           
           !Problems
          @@ -1448,14 +1448,14 @@ As a //first shot// Ichthyo considers the following approach:
           # Some (not all) parts of the core application are non-deterministic. That means, we can't tie the memory management to any assumptions on behalf of the execution path
           
           !C++ solution
          -First of all -- this doesn't concern //every// allocation. It rather means there are certain //dangerous areas// which need to be identified. And as always, instead of carrying the inherent complexities of the problem into the solution, we should rather look for a common solution pattern which helps factoring out the complexity.
          +First of all -- this doesn't concern //every// allocation. It rather means there are certain //dangerous areas// which need to be identified. Anyhow, instead of carrying inherent complexities of the problem into the solution, we should rather look for  common solution pattern(s) which help factoring out complexity.
           
          -For the case in question this seems to be the ''resource allocation is construction'' pattern. Which boils down to basically never using bare pointers when concerned with ownership. Instead, ownership should be handled by smart-pointers.
          +For the case here in question this seems to be the ''resource allocation is construction'' pattern. Which boils down to basically never using bare pointers when concerned with ownership. Instead, ownership should be handled by smart-pointers.
           
           !!usage scenarios
           # __existence is being used__: Objects just live for being referred to in a object network. In this case, use refcounting smart-pointers for every ref. (note: problem with cyclic refs)
           # __entity bound ownership__: Objects can be tied to some long living entity in the program, which holds the smart-pointer
          -#* if the existence of these ref-holding entity can be //guaranteed// (like a contract), then the other users can build a object network with conventional pointers
          +#* if the existence of these ref-holding entity can be //guaranteed// (as if by contract), then the other users can build a object network with conventional pointers
           #* otherwise, when the ref-holding entity //can disappear// in a regular program state, we need weak-refs and checking (because by our postulate the controlled resource needs to be destructed immediately, otherwise we would have the first case, existence == being used)
           
           !!!dangerous uses
          @@ -1470,7 +1470,7 @@ For the case in question this seems to be the ''resource allocation is construct
           * the EDL and the defined [[Asset]]s belong together to one Session. If the Session is closed, this means a internal shutdown of the whole ProcLayer, i.e. closing of all GUI representations and terminating all render processes. If these calles are implemented as blocking operations, we can assert that as long as any GUI representation or any render process is running, there is a valid Session and EDL.
           
           !using Factories
          -And, last but not least, doing all actual allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides that, the ProcLayer code shouldn't issue "new" and "delete", rather it should use some central [[Factories]] for all allocation and freeing, so we can redirect these calls down to the backend, which may use pooling or special placement allocators or the like. The rationale is, for modern hardware/architectures, care has to be taken with heap allocations, esp. with many small objects and irregular usage patterns.
          +And, last but not least, doing all actual allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides, the ProcLayer code shouldn't issue "new" and "delete" when it comes in hand, rather it should use some centralized [[Factories]] for all allocation and freeing, so we can redirect these calls down to the backend, which may use pooling or special placement allocators or the like. The rationale is, for modern hardware/architectures, care has to be taken with heap allocations, esp. with many small objects and irregular usage patterns.
           
          From 49459b4bf7a923145cea4478c84c540d5437036a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 20 Nov 2007 05:20:01 +0100 Subject: [PATCH 17/22] Fix inheritance of asset::Unknown, fix broken test, enable MakeClip_test --- doc/devel/uml/class136709.html | 2 +- doc/devel/uml/class137477.html | 3 +- doc/devel/uml/class137605.html | 3 +- doc/devel/uml/fig130309.png | Bin 40294 -> 40327 bytes doc/devel/uml/fig130437.png | Bin 44658 -> 41996 bytes doc/devel/uml/index.html | 2 +- doc/devel/uml/index_70.html | 2 +- doc/devel/uml/index_73.html | 2 +- doc/devel/uml/index_79.html | 2 +- doc/devel/uml/index_83.html | 4 +-- doc/devel/uml/index_84.html | 2 +- src/common/util.hpp | 2 +- src/proc/asset/preview.cpp | 22 +++--------- src/proc/asset/preview.hpp | 8 ++--- src/proc/asset/unknown.cpp | 35 ++++++++++++++++--- src/proc/asset/unknown.hpp | 17 +++++++-- src/proc/mobject/placement.hpp | 26 ++++++++++---- src/proc/mobject/session/clip.cpp | 3 +- src/proc/mobject/session/clip.hpp | 21 ++--------- src/proc/mobject/session/effect.hpp | 18 ++-------- src/proc/mobject/session/meta.hpp | 18 ++-------- tests/51asset.tests | 3 +- tests/components/proc/asset/makecliptest.cpp | 3 +- uml/cinelerra3/128133 | 18 +++++----- uml/cinelerra3/129285 | 2 +- uml/cinelerra3/130309.diagram | 28 +++++++-------- uml/cinelerra3/130437.diagram | 32 ++++++++--------- uml/cinelerra3/5.session | 8 +++-- uml/cinelerra3/cinelerra3.prj | 2 +- 29 files changed, 144 insertions(+), 144 deletions(-) diff --git a/doc/devel/uml/class136709.html b/doc/devel/uml/class136709.html index 1117fdbef..b07b2cdc6 100644 --- a/doc/devel/uml/class136709.html +++ b/doc/devel/uml/class136709.html @@ -16,7 +16,7 @@ -

          Declaration :

          • C++ : class Media : public Asset

          Directly inherited by : Clip CompoundMedia Preview

          +

          Declaration :

          • C++ : class Media : public Asset

          Directly inherited by : Clip CompoundMedia Unknown

          key abstraction: media-like assets

          Artifact : media

          Operation createClip

          Declaration :

          • Uml : + createClip() : Clip
          • C++ : public: Clip createClip ()

          create a (possibly compound) Clip refering to this media, ready to be added to the EDL.

          diff --git a/doc/devel/uml/class137477.html b/doc/devel/uml/class137477.html index 18188f2f5..8f5631895 100644 --- a/doc/devel/uml/class137477.html +++ b/doc/devel/uml/class137477.html @@ -16,7 +16,8 @@ -

          Declaration :

          • C++ : class Unknown : public Preview

          placeholder for unknown or unavailable media source

          Artifact : unknown

          +

          Declaration :

          • C++ : class Unknown : public Media

          Directly inherited by : Preview

          +

          placeholder for unknown or unavailable media source

          Artifact : unknown

          All public operations : createClip , enable , getDependant , getParents , howtoProc , isActive

          diff --git a/doc/devel/uml/class137605.html b/doc/devel/uml/class137605.html index 7ba8853f4..f8942d22a 100644 --- a/doc/devel/uml/class137605.html +++ b/doc/devel/uml/class137605.html @@ -16,8 +16,7 @@ -

          Declaration :

          • C++ : class Preview : public Media

          Directly inherited by : Unknown

          -

          alternative version of the media data, probably with lower resolution

          Artifact : preview

          +

          Declaration :

          • C++ : class Preview : public Unknown

          alternative version of the media data, probably with lower resolution

          Artifact : preview

          All public operations : createClip , enable , getDependant , getParents , howtoProc , isActive

          diff --git a/doc/devel/uml/fig130309.png b/doc/devel/uml/fig130309.png index a75f29b5a71707aa64710a00caa15103012a0651..8e7461c94430f1cb85b888d6e71093af24157686 100644 GIT binary patch delta 21373 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 Uf6SYW0ssI207*qoM6N<$f>n8v0{{R3 diff --git a/doc/devel/uml/fig130437.png b/doc/devel/uml/fig130437.png index 3a504a003ef754f91e99b4fa50310eda969c58ae..e9cfd85120172e50128dfb21e6daeb096b9437fa 100644 GIT binary patch literal 41996 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≧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 diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index 6d7dfdc87..7cd9d2895 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -112,7 +112,7 @@ Documentation
          Artifact Cinelerra3

          Depends on common

          Depends on gui

          Depends on proc

          Depends on backend

          the main executable to be built

          -

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

          +

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

          Artifact main

          Artifact source

          diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 485f245e8..10124ce04 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -33,8 +33,8 @@ FixedLocationclass Fixtureactivity object fixtureartifactthe (low level) representation of the EDL with concrete placement data -Fixturecomponent Fixtureclass +Fixturecomponent fixturerelation fork activity nodefork activity node FrameclassFrames are just a low level lump of continous memory, most parts are opaque. Frames are memory sensitive, they will be small constant sized structures which can be efficently managed in a pool. diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 798945020..27e37a604 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,9 +20,9 @@ idattributeAsset primary key. In Memory Databaseclass diagram inFixtureactivity action pin +inputclass instance inputclass instance inputclass instance -inputclass instance instanceoperation instructionsrelation Interfaceclass view diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index 2a52fbc5c..4902abfdc 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,9 +19,9 @@ NameKindDescription offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation? orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core cinelerra-3 codebase is "cin3". +ouputclass instance ouputclass instance ouputclass instance -ouputclass instance OutPortclassstructural asset corresponding to some port generating media output outportartifactstructural asset corresponding to some port generating media output outputrelation diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index d8d717c8e..5c1a18530 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -21,8 +21,8 @@ saveoperationcreate a complete, serialized representation
          of the current session config and contents.
          @todo how to serialize, prameters, return value? Schedulerclass segmentartifactSegment of the Timeline.
          Used at the moment (7/07) for partitioning the timeline/fixture into segments
          to be rendered by a specialized render node network for each, without the need
          to change any connections within a given segment.
          Note this concept may be superfluos alltogether; is a draft and the real
          use still needs to be worked out... -segment Toolactivity object Segmentclass +segment Toolactivity object SegmentationToolclassTool implementation for deriving a partitioning of the current timeline such, that each segement has a constant configuration. "Constant" means here, that any remaining changes over time can be represented by automation solely, without the need to change the node connections. segmentationtoolartifactTool for creating a partitioning of the current timeline segmentsactivity object @@ -46,8 +46,8 @@ SimpleClipclassElementary clip consisting of only one media stream SmartPointerclass SmartPointersclass view -sourcerelationmedia source of this clip sourcerelationthe media source this clip referes to +sourcerelationmedia source of this clip SourceclassSource Node: represents a media source to pull data from. sourceartifactRepresentation of a Media source Source Overviewdeployment diagram diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 03ef3d02c..686d34aef 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -32,8 +32,8 @@ toolfactoryartifactsupply of Tool implementations for the Builder Trackclassstructural asset holding the configuration of a track in the EDL trackattribute -trackartifactstructural asset holding the configuration of a track in the EDL trackartifactdescriptor for one track in the Session +trackartifactstructural asset holding the configuration of a track in the EDL Trackclass tracksrelationelementary media assets comprising this compound tracksrelation diff --git a/src/common/util.hpp b/src/common/util.hpp index ea21c2a9c..31c380be0 100644 --- a/src/common/util.hpp +++ b/src/common/util.hpp @@ -177,6 +177,6 @@ namespace util /** shortcut for subclass test, intended for assertions only. * @note it is considered bad style to use such in non-assertion code, * and we probably will enforce this design rule in future. */ -#define INSTANCEOF(CLASS, EXPR) (dynamic_cast (EXPR)) +#define INSTANCEOF(CLASS, EXPR) (dynamic_cast (EXPR)) #endif /*UTIL_HPP_*/ diff --git a/src/proc/asset/preview.cpp b/src/proc/asset/preview.cpp index 212e85666..d626d7525 100644 --- a/src/proc/asset/preview.cpp +++ b/src/proc/asset/preview.cpp @@ -50,28 +50,16 @@ namespace asset /** create a preview placeholder ("proxy media") for the given - * media asset + * media asset. The name of the created media asset is derived + * by decorating the original media's name. */ Preview::Preview (const Media& mediaref) - : Media (createProxyIdent (mediaref.ident), - mediaref.getFilename(), - mediaref.getLength()) + : Unknown (createProxyIdent (mediaref.ident), + mediaref.getFilename(), + mediaref.getLength()) { UNIMPLEMENTED ("do something to setup proxy media"); } - - - - /** create a dummy placeholder - * @internal for use by asset::Unknown - * @todo better design! - */ - Preview::Preview (const Asset::Ident& idi, string name, Time length) - : Media (createProxyIdent (idi), - name, length) - { - TODO ("work out how to handle unknown media placheholder"); - } diff --git a/src/proc/asset/preview.hpp b/src/proc/asset/preview.hpp index abf3734f3..0d2176b5e 100644 --- a/src/proc/asset/preview.hpp +++ b/src/proc/asset/preview.hpp @@ -24,7 +24,7 @@ #ifndef ASSET_PREVIEW_H #define ASSET_PREVIEW_H -#include "proc/asset/media.hpp" +#include "proc/asset/unknown.hpp" @@ -32,13 +32,13 @@ namespace asset { /** - * alternative version of the media data, probably with lower resolution + * special placeholder denoting an alternative version of the media data, + * typically with lower resolution ("proxy media") */ - class Preview : public Media + class Preview : public Unknown { protected: Preview (const Media& mediaref); - Preview (const Asset::Ident& idi, string name, Time length); friend class MediaFactory; }; diff --git a/src/proc/asset/unknown.cpp b/src/proc/asset/unknown.cpp index 357db430b..3e3620cdc 100644 --- a/src/proc/asset/unknown.cpp +++ b/src/proc/asset/unknown.cpp @@ -22,19 +22,44 @@ #include "proc/asset/unknown.hpp" +#include + + +using boost::format; namespace asset { - const cinelerra::Time DUMMY_TIME (25); - /** */ - Unknown::Unknown (const Asset::Ident& idi) - : Preview (idi, "", DUMMY_TIME) + /** create a placeholder for a media with the given identity. + * the denoted original media (identity) can be accessed later + * on using the Unknown::getOrg() function */ + Unknown::Unknown (const Asset::Ident& idi, string name, Time length) + : Media (idi, name, length) { - TODO ("do something sensible with the »unknown media« placeholder..."); + TODO ("implement some sensible behaviour for the »unknown media« placeholder..."); } + /** using the information stored in this placeholder asset, + * try to access the "real" media it stands for. + */ + Media::PMedia + Unknown::getOrg() throw(cinelerra::error::Invalid) + { + UNIMPLEMENTED ("how to get at the original media from a »Unknown« placeholder"); + if (1==0) + throw cinelerra::error::Invalid (str(format("Unable to locate original media " + "for ID=%s, filename=\"%s\".") + % string(this->ident) + % string(this->getFilename())) + ,CINELERRA_ERROR_ORIG_NOT_FOUND + ); + } + + CINELERRA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media refered by placeholder not found"); + + + } // namespace asset diff --git a/src/proc/asset/unknown.hpp b/src/proc/asset/unknown.hpp index 85db2ac81..ce89daa90 100644 --- a/src/proc/asset/unknown.hpp +++ b/src/proc/asset/unknown.hpp @@ -24,24 +24,35 @@ #ifndef ASSET_UNKNOWN_H #define ASSET_UNKNOWN_H -#include "proc/asset/preview.hpp" +#include "proc/asset/media.hpp" namespace asset { + + const cinelerra::Time DUMMY_TIME (25); ///< @todo solve konfig management /** * Placeholder Asset for unknown or unavailable media source. + * @todo maybe do special handling of the media length, allowing + * it to support existing clips even if the media length + * is not known? */ - class Unknown : public Preview + class Unknown : public Media { protected: - Unknown (const Asset::Ident& idi); + Unknown (const Asset::Ident& idi, string name="", Time length=DUMMY_TIME); friend class MediaFactory; + + public: + virtual Media::PMedia getOrg() throw(cinelerra::error::Invalid); + }; + CINELERRA_ERROR_DECLARE (ORIG_NOT_FOUND); + diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 1e574580b..e1f1e48c6 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -130,12 +130,26 @@ namespace mobject /* === defining specialisations to be subclasses === */ - - - - - /////TODO: define Macro for specialisations here - + +#define DEFINE_SPECIALIZED_PLACEMENT(SUBCLASS) \ + template<> \ + class Placement : public Placement \ + { \ + protected: \ + Placement (SUBCLASS & m, void (*moKiller)(MObject*)) \ + : Placement::Placement (m, moKiller) \ + { }; \ + friend class session::MObjectFactory; \ + \ + public: \ + virtual SUBCLASS* \ + operator-> () const \ + { \ + ENSURE (INSTANCEOF (SUBCLASS, this->get())); \ + return static_cast \ + (shared_ptr::operator-> ()); \ + } \ + }; /* a note to the maintainer: please don't add any fields or methods to * these subclasses which aren't also present in Placement! diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp index e5e097073..68333f36e 100644 --- a/src/proc/mobject/session/clip.cpp +++ b/src/proc/mobject/session/clip.cpp @@ -50,7 +50,8 @@ namespace mobject bool Clip::isValid () const { - UNIMPLEMENTED ("check consistency of clip length def, implies accessing the underlying media def"); + TODO ("check consistency of clip length def, implies accessing the underlying media def"); + return length > 0; } diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index ab25f8a76..0843de9d5 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -82,25 +82,8 @@ namespace mobject } // namespace mobject::session - - ///////////////////////////TODO use macro for specialsation... - template<> - class Placement : public Placement - { - protected: - Placement (session::Clip & m, void (*moKiller)(MObject*)) - : Placement::Placement (m, moKiller) - { }; - friend class session::MObjectFactory; - - public: - virtual session::Clip* - operator-> () const - { - ENSURE (INSTANCEOF(session::Clip, &(*this))); - return static_cast (shared_ptr::operator-> ()); - } - }; + /** Placement defined to be subclass of Placement */ + DEFINE_SPECIALIZED_PLACEMENT (session::Clip); } // namespace mobject diff --git a/src/proc/mobject/session/effect.hpp b/src/proc/mobject/session/effect.hpp index b79ba2f93..fa034e6b6 100644 --- a/src/proc/mobject/session/effect.hpp +++ b/src/proc/mobject/session/effect.hpp @@ -50,22 +50,8 @@ namespace mobject } // namespace mobject::session - ///////////////////////////TODO use macro for specialsation... - template<> - class Placement : public Placement - { - Placement (session::Effect & m, void (*moKiller)(MObject*)) - : Placement::Placement (m, moKiller) - { }; - - public: - virtual session::Effect* - operator-> () const - { - ENSURE (INSTANCEOF(session::Effect, &(*this))); - return static_cast (shared_ptr::operator-> ()); - } - }; + /** Placement defined to be subclass of Placement */ + DEFINE_SPECIALIZED_PLACEMENT (session::Effect); } // namespace mobject #endif diff --git a/src/proc/mobject/session/meta.hpp b/src/proc/mobject/session/meta.hpp index e41231e2c..108c3e6dc 100644 --- a/src/proc/mobject/session/meta.hpp +++ b/src/proc/mobject/session/meta.hpp @@ -49,22 +49,8 @@ namespace mobject } // namespace mobject::session - //////////////////////////////////TODO - template<> - class Placement : public Placement - { - Placement (session::Meta & m, void (*moKiller)(MObject*)) - : Placement::Placement (m, moKiller) - { }; - - public: - virtual session::Meta* - operator-> () const - { - ENSURE (INSTANCEOF(session::Meta, &(*this))); - return static_cast (shared_ptr::operator-> ()); - } - }; + /** Placement defined to be subclass of Placement */ + DEFINE_SPECIALIZED_PLACEMENT (session::Meta); } // namespace mobject #endif diff --git a/tests/51asset.tests b/tests/51asset.tests index e105623eb..06882dbca 100644 --- a/tests/51asset.tests +++ b/tests/51asset.tests @@ -33,7 +33,8 @@ return: 0 END -PLANNED "MakeClip_test" MakeClip_test <getLength()); ASSERT (cm->ident.category.hasKind (VIDEO)); ASSERT (cm->getFilename() == mm->getFilename()); - ASSERT (cm->howtoProc() == mm->howtoProc()); +TODO ("implement Processing Pattern!!!"); +// ASSERT (cm->howtoProc() == mm->howtoProc()); ASSERT (cm->ident.org == mm->ident.org); ASSERT (dependencyCheck (mm,cm)); diff --git a/uml/cinelerra3/128133 b/uml/cinelerra3/128133 index 8438588b6..aefe38ecb 100644 --- a/uml/cinelerra3/128133 +++ b/uml/cinelerra3/128133 @@ -1,6 +1,6 @@ format 40 "Asset" // ProcessingLayer::Asset - revision 14 + revision 15 modified_by 5 "hiv" // class settings //class diagram settings @@ -593,12 +593,12 @@ ${inlines} explicit_switch_type "" comment "placeholder for unknown or unavailable media source" - classrelation 140933 // - relation 139141 ---|> + classrelation 146181 // + relation 144005 ---|> a public cpp default "${type}" - classrelation_ref 140933 // - b multiplicity "" parent class_ref 137605 // Preview + classrelation_ref 146181 // + b multiplicity "" parent class_ref 136709 // Media end end @@ -614,12 +614,12 @@ ${inlines} explicit_switch_type "" comment "alternative version of the media data, probably with lower resolution" - classrelation 140805 // - relation 139013 ---|> + classrelation 146309 // + relation 144133 ---|> a public cpp default "${type}" - classrelation_ref 140805 // - b multiplicity "" parent class_ref 136709 // Media + classrelation_ref 146309 // + b multiplicity "" parent class_ref 137477 // Unknown end end diff --git a/uml/cinelerra3/129285 b/uml/cinelerra3/129285 index 551a99b4b..26d96af1d 100644 --- a/uml/cinelerra3/129285 +++ b/uml/cinelerra3/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 6 + revision 7 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/cinelerra3/130309.diagram b/uml/cinelerra3/130309.diagram index d9d44ae03..81e77861e 100644 --- a/uml/cinelerra3/130309.diagram +++ b/uml/cinelerra3/130309.diagram @@ -37,11 +37,11 @@ classcanvas 131077 class_ref 137349 // Clip end classcanvas 131333 class_ref 137477 // Unknown draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 381 529 2000 + xyz 381 445 2000 end classcanvas 131461 class_ref 137605 // Preview draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 386 445 2005 + xyz 386 529 2005 end classcanvas 131973 class_ref 137733 // Effect 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 @@ -126,17 +126,6 @@ relationcanvas 131205 relation_ref 138757 // line 134405 z 1999 to ref 128645 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 131717 relation_ref 139013 // - geometry VHV - from ref 131461 z 2004 to point 410 423 - line 134021 z 2004 to point 292 423 - line 134149 z 2004 to ref 128645 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 131845 relation_ref 139141 // - from ref 131333 z 1999 to ref 131461 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 132229 relation_ref 139269 // from ref 131973 z 1999 to ref 128773 no_role_a no_role_b @@ -168,7 +157,7 @@ relationcanvas 134533 relation_ref 140421 // no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 134917 relation_ref 140549 // - from ref 133765 z 2004 stereotype "<>" xyz 228 493 3000 to point 225 545 + from ref 133765 z 2004 stereotype "<>" xyz 230 500 3000 to point 225 545 line 135301 z 2004 to point 225 365 line 135173 z 2004 to ref 128645 role_a_pos 216 343 3000 no_role_b @@ -207,6 +196,17 @@ relationcanvas 137861 relation_ref 142213 // line 137989 z 1999 to ref 128773 role_a_pos 556 343 3000 no_role_b multiplicity_a_pos 556 376 3000 no_multiplicity_b +relationcanvas 138117 relation_ref 144005 // + geometry VHV + from ref 131333 z 1999 to point 410 423 + line 138245 z 1999 to point 292 423 + line 138373 z 1999 to ref 128645 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 138501 relation_ref 144133 // + from ref 131461 z 1999 to ref 131333 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b line 128261 -_-_ geometry HV from ref 128005 z 1999 to point 331 150 line 128389 z 1999 to ref 128133 diff --git a/uml/cinelerra3/130437.diagram b/uml/cinelerra3/130437.diagram index 2388a38ee..59657b515 100644 --- a/uml/cinelerra3/130437.diagram +++ b/uml/cinelerra3/130437.diagram @@ -10,11 +10,11 @@ classcanvas 128133 class_ref 136709 // Media end classcanvas 128261 class_ref 137477 // Unknown draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 530 231 2000 + xyz 530 147 2000 end classcanvas 128389 class_ref 137605 // Preview draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 535 147 2005 + xyz 535 215 2005 end classcanvas 128901 class_ref 128901 // Clip 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 @@ -108,18 +108,10 @@ classcanvas 142981 class_ref 137861 // Codec draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 618 480 2004 end -relationcanvas 128517 relation_ref 139141 // - from ref 128261 z 1999 to ref 128389 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 128645 relation_ref 138757 // from ref 128005 z 1999 to ref 128133 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 128773 relation_ref 139013 // - from ref 128389 z 2004 to ref 128133 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 129541 relation_ref 129413 // from ref 128901 z 1999 to ref 129157 no_role_a no_role_b @@ -186,9 +178,9 @@ relationcanvas 137349 relation_ref 140421 // no_multiplicity_a no_multiplicity_b relationcanvas 137477 relation_ref 140549 // from ref 137221 z 1999 to point 648 76 - line 137733 z 1999 stereotype "<>" xyz 652 122 3000 to ref 128133 - role_a_pos 609 54 3000 no_role_b - multiplicity_a_pos 584 121 3000 multiplicity_b_pos 636 122 3000 + line 137733 z 1999 stereotype "<>" xyz 634 112 3000 to ref 128133 + role_a_pos 634 60 3000 no_role_b + multiplicity_a_pos 611 60 3000 multiplicity_b_pos 636 122 3000 relationcanvas 137861 relation_ref 140677 // from ref 128901 z 1999 to point 218 232 line 138245 z 1999 to point 377 48 @@ -241,11 +233,11 @@ relationcanvas 142213 relation_ref 142085 // from ref 141317 z 1999 to point 812 270 line 142341 z 1999 to point 812 131 line 142469 z 1999 to ref 139013 - role_a_pos 794 109 3000 no_role_b + role_a_pos 776 272 3000 no_role_b multiplicity_a_pos 794 142 3000 multiplicity_b_pos 794 299 3000 relationcanvas 142597 relation_ref 142213 // - from ref 141189 z 1999 stereotype "<>" xyz 656 360 3000 to ref 141061 - role_a_pos 650 367 3000 no_role_b + from ref 141189 z 1999 stereotype "<>" xyz 660 352 3000 to ref 141061 + role_a_pos 645 374 3000 no_role_b multiplicity_a_pos 614 367 3000 no_multiplicity_b relationcanvas 142853 relation_ref 139269 // from ref 142725 z 1999 to ref 141061 @@ -255,4 +247,12 @@ relationcanvas 143109 relation_ref 139397 // from ref 142981 z 1999 to ref 141061 no_role_a no_role_b no_multiplicity_a no_multiplicity_b +relationcanvas 143237 relation_ref 144133 // + from ref 128389 z 1999 to ref 128261 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 143365 relation_ref 144005 // + from ref 128261 z 1999 to ref 128133 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b end diff --git a/uml/cinelerra3/5.session b/uml/cinelerra3/5.session index 9440f200a..7ce3a373f 100644 --- a/uml/cinelerra3/5.session +++ b/uml/cinelerra3/5.session @@ -1,16 +1,20 @@ window_sizes 1140 783 270 860 633 71 diagrams classdiagram_ref 130309 // Asset Kinds - 860 633 100 4 0 0 - active classdiagram_ref 128133 // Session structure + 860 633 100 4 120 0 + classdiagram_ref 128133 // Session structure 860 633 100 4 0 0 classdiagram_ref 128389 // Render Entities 688 506 100 4 120 0 + active classdiagram_ref 130437 // Media-Asset Relations + 859 616 100 4 0 0 end show_stereotypes selected package_ref 129 // cinelerra3 open + class_ref 137477 // Unknown + class_ref 137605 // Preview class_ref 128645 // Placement class_ref 129413 // RelativeLocation class_ref 129541 // Allocation diff --git a/uml/cinelerra3/cinelerra3.prj b/uml/cinelerra3/cinelerra3.prj index 78317c6ff..a6f8a2a7f 100644 --- a/uml/cinelerra3/cinelerra3.prj +++ b/uml/cinelerra3/cinelerra3.prj @@ -1,6 +1,6 @@ format 40 "cinelerra3" - revision 36 + revision 37 modified_by 5 "hiv" cpp_root_dir "../../src/" From 66daf409d45bbaa13dde0ae61922e56e2e82360c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 21 Nov 2007 06:08:01 +0100 Subject: [PATCH 18/22] specify (as test) how asset dependency should work --- src/common/util.hpp | 6 +- src/proc/asset.cpp | 2 +- src/proc/asset.hpp | 6 +- .../proc/asset/dependantassetstest.cpp | 128 +++++++++++++++++- .../proc/asset/identityofassetstest.cpp | 1 - tests/components/proc/asset/testasset.hpp | 107 +++++++++++++++ .../proc/mobject/session/testclip.cpp | 4 +- .../proc/mobject/session/testclip.hpp | 7 +- 8 files changed, 241 insertions(+), 20 deletions(-) create mode 100644 tests/components/proc/asset/testasset.hpp diff --git a/src/common/util.hpp b/src/common/util.hpp index 31c380be0..6d5119b14 100644 --- a/src/common/util.hpp +++ b/src/common/util.hpp @@ -98,8 +98,10 @@ namespace util inline bool contains (SEQ& cont, typename SEQ::value_type& val) { - typename SEQ::iterator end = cont.end(); - return end != std::find(cont.begin(),end, val); + typename SEQ::const_iterator begin = cont.begin(); + typename SEQ::const_iterator end = cont.end(); + + return end != std::find(begin,end, val); } /** shortcut for removing all copies of an Element diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index f9136bb20..ec75d84b3 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -94,7 +94,7 @@ namespace asset * on the enablement status of parent assets as well. */ void - Asset::enable () throw(cinelerra::error::State) + Asset::enable (bool on) throw(cinelerra::error::State) { UNIMPLEMENTED ("enable/disable Assets."); } diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index ebac8bd7a..0c304a5de 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -98,7 +98,7 @@ namespace asset const size_t hash; ID (size_t id) : hash(id) {} ID (const KIND& asset) : hash(asset.getID()) {} - operator size_t() const { return hash; } + operator size_t() const { return hash; } }; class Asset; @@ -248,7 +248,7 @@ namespace asset friend class AssetManager; private: - void unregister (PAsset& other); + void unregister (PAsset& other); @@ -274,7 +274,7 @@ namespace asset * Note the corresponding #isActive predicate may * depend on the enablement status of parent assets as well */ - void enable () throw(cinelerra::error::State); + void enable (bool on=true) throw(cinelerra::error::State); }; diff --git a/tests/components/proc/asset/dependantassetstest.cpp b/tests/components/proc/asset/dependantassetstest.cpp index 9b52be4c0..82265a168 100644 --- a/tests/components/proc/asset/dependantassetstest.cpp +++ b/tests/components/proc/asset/dependantassetstest.cpp @@ -22,15 +22,16 @@ #include "common/test/run.hpp" -//#include "common/factory.hpp" -//#include "common/util.hpp" +#include "proc/asset/testasset.hpp" +#include "common/util.hpp" //#include #include +using util::isnil; +using util::contains; //using boost::format; using std::string; -using std::cout; namespace asset @@ -49,10 +50,127 @@ namespace asset */ class DependantAssets_test : public Test { - virtual void run(Arg arg) + virtual void run (Arg arg) + { + checkDependencyMechanics (); + checkUnlinking (); + TODO ("activate missing testcases"); +/////TODO checkEnablementPropagation (); +/////TODO checkRealAssetDependencyRegistration (); + } + + typedef TestAsset TA; + typedef TA::PA PTestA; + + /** @test check operation of basic asset dependency support + */ + void checkDependencyMechanics () + { + PAsset a1 = TA::create(); + ASSERT (isnil (a1->getParents())); + ASSERT (isnil (a1->getDependant())); + + PTestA a2 = TA::create(a1); + ASSERT (a1 == a2->getParents()[0]); // TestAsset registered a1 as parent + ASSERT (a2 == a1->getDependant()[0]); + + TRACE(test, "a1.cnt=%i",a1.use_count()); + TRACE(test, "a2.cnt=%i",a2.use_count()); + PAsset a3 = TA::create(); + a2->set_depend(a3); + ASSERT (a3 == a2->getParents()[1]); + ASSERT (a2 == a3->getDependant()[0]); + ASSERT (!contains (a1->getDependant(), a3)); + } + + + /** @test unlink operation removing inter asset links + */ + void checkUnlinking () + { + PTestA a1_ = TA::create(); + PAsset a1 (a1_); + PTestA a2_ = TA::create(a1); + PAsset a2 (a2_); + ASSERT (a1 == a2->getParents()[0]); + ASSERT (a2 == a1->getDependant()[0]); + + a2_->call_unlink(); + ASSERT (isnil (a2->getParents())); + ASSERT (isnil (a2->getDependant())); + ASSERT (!contains (a1->getDependant(), a2)); // has been propagated + + a2_->set_depend(a1); + PAsset a3 = TA::create(a1); + ASSERT (a1 == a2->getParents()[0]); + ASSERT (a1 == a3->getParents()[0]); + ASSERT (a2 == a1->getDependant()[0]); + ASSERT (a3 == a1->getDependant()[1]); + + a1_->call_unlink(a3->getID()); + ASSERT (!contains (a1->getDependant(), a3)); // selectively removed + ASSERT ( contains (a1->getDependant(), a2)); + ASSERT (a1 == a3->getParents()[0]); // no propagation + } + + + /** @test enabling and disabling an asset should + * propagate to dependant assets + */ + void checkEnablementPropagation () + { + PAsset a1 = TA::create(); + PAsset a2 = TA::create(a1); + PAsset a3 = TA::create(); // not dependant + + ASSERT (a1->isActive()); + ASSERT (a2->isActive()); + ASSERT (a3->isActive()); + + a1->enable(false); + ASSERT (!a1->isActive()); + ASSERT (!a2->isActive()); + ASSERT (a3->isActive()); + + a2->enable(true); + ASSERT (!a1->isActive()); + ASSERT (!a2->isActive()); // ignored because parent is disabled + + a1->enable(true); + ASSERT (a1->isActive()); + ASSERT (a2->isActive()); + + a2->enable(false); + ASSERT (a1->isActive()); + ASSERT (!a2->isActive()); // disabling not propagated to parent + a2->enable(true); + ASSERT (a1->isActive()); + ASSERT (a2->isActive()); + + a3->enable(false); + ASSERT (a1->isActive()); + ASSERT (a2->isActive()); + ASSERT (!a3->isActive()); // no dependency... + + a1->enable(false); + a3->enable(); + ASSERT (!a1->isActive()); + ASSERT (!a2->isActive()); + ASSERT (a3->isActive()); + } + + + /** @test each real world asset subclass has to care + * for registering and deregistering any additional + * dependencies. Here we collect some more prominent + * examples (and hopfully don't fail to cover any + * important special cases...) + */ + void checkRealAssetDependencyRegistration () { UNIMPLEMENTED ("handling of Asset dependencies"); - } + } + }; diff --git a/tests/components/proc/asset/identityofassetstest.cpp b/tests/components/proc/asset/identityofassetstest.cpp index 2e62963bc..05a6e0ae9 100644 --- a/tests/components/proc/asset/identityofassetstest.cpp +++ b/tests/components/proc/asset/identityofassetstest.cpp @@ -46,7 +46,6 @@ namespace asset * @test creating several Assets and checking object identity, * detection of duplicates and version handling. * @see proc_interface::AssetManager#reg - * @todo to be written; features are missing as of 9/07 */ class IdentityOfAssets_test : public Test { diff --git a/tests/components/proc/asset/testasset.hpp b/tests/components/proc/asset/testasset.hpp new file mode 100644 index 000000000..b40ac3a77 --- /dev/null +++ b/tests/components/proc/asset/testasset.hpp @@ -0,0 +1,107 @@ +/* + TESTASSET.hpp - test asset (stub) for checking internal asset functionality + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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 ASSET_TESTASSET_H +#define ASSET_TESTASSET_H + + +#include "proc/asset.hpp" +//#include "common/util.hpp" + + +#include + +using std::tr1::shared_ptr; +using boost::format; +using std::string; + + +namespace asset + { + namespace test + { + + namespace + { + uint counter (0); + + /** @internal helper generating continuosely + * different new asset identities + */ + Asset::Ident + make_ident () + { + return Asset::Ident ( str(format("TestAsset.%i") % counter) + , Category (META) + , "test" + , counter++ + ); + } + Asset::Ident + make_ident (PAsset& ref) + { + return Asset::Ident ( str(format("%s-TestAsset.%i") % ref->ident.name + % counter) + , ref->ident.category + , "test" + , counter++ + ); + } + } + + + + /** + * Test(mock) asset subclass usable for hijacking a given + * asset class (template parameter) and subsequently accessing + * internal facillities for writing unit tests. Prerequisite + * for using this template is that the used asset base class + * has a (protected) ctor taking an Asset::Ident.... + */ + template + class TestAsset : public A + { + TestAsset () : A(make_ident ()) { }; + TestAsset (PAsset& pRef) : A(make_ident (pRef)) { this->defineDependency(pRef); }; + + static void deleter (TestAsset* aa) { delete aa; } + + public: + typedef shared_ptr > PA; + + static PA create () { return PA (new TestAsset, &deleter); } + static PA create (PAsset& pRef) { return PA (new TestAsset (pRef), &deleter); } + + /* === interesting asset features we want to access for tests === */ + void call_unlink () { this->unlink (); } + void call_unlink (IDA target) { this->unlink (target); } + void set_depend (PAsset parent) { this->defineDependency (parent); } + + }; + + + + } // namespace test + +} // namespace asset +#endif diff --git a/tests/components/proc/mobject/session/testclip.cpp b/tests/components/proc/mobject/session/testclip.cpp index e91ac5ed9..0d1f4f451 100644 --- a/tests/components/proc/mobject/session/testclip.cpp +++ b/tests/components/proc/mobject/session/testclip.cpp @@ -1,5 +1,5 @@ /* - TestClip - bookkeeping (asset) view of a media clip. + TestClip - test clip (stub) for checking EDL/Session functionality Copyright (C) CinelerraCV 2007, Christian Thaeter @@ -70,7 +70,7 @@ namespace mobject { } }; - cinelerra::Singleton testbed_1; + cinelerra::Singleton testbed_1; // invoke ctor when creating first TestClip... diff --git a/tests/components/proc/mobject/session/testclip.hpp b/tests/components/proc/mobject/session/testclip.hpp index 0e60a0ce8..edb3369ff 100644 --- a/tests/components/proc/mobject/session/testclip.hpp +++ b/tests/components/proc/mobject/session/testclip.hpp @@ -25,20 +25,15 @@ #define MOBJECT_SESSION_TESTCLIP_H -#include "common/test/run.hpp" -#include "common/factory.hpp" - #include "proc/mobject/session/clip.hpp" //#include "common/util.hpp" //#include -#include using std::tr1::shared_ptr; //using boost::format; using std::string; -using std::cout; namespace mobject @@ -55,7 +50,7 @@ namespace mobject * @todo make this usable as Mock object to record invoked operations. * */ - class TestClip : public mobject::session::Clip /////////////TODO how this???? + class TestClip : public mobject::session::Clip { TestClip (); From 95af2d50ccca284e0ecce332bbb7d438e2df6b8b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 22 Nov 2007 06:26:55 +0100 Subject: [PATCH 19/22] worked out some important details of deleting and unlinking assets --- src/common/singletonpolicies.hpp | 2 +- src/nobugcfg.h | 2 ++ src/proc/asset.cpp | 15 ++++++--- src/proc/asset.hpp | 2 ++ src/proc/asset/db.hpp | 32 +++++++++++++++++-- src/proc/assetmanager.cpp | 26 ++++++++------- src/proc/assetmanager.hpp | 8 ++--- .../proc/asset/dependantassetstest.cpp | 20 +++++++----- wiki/renderengine.html | 26 +++++++++++---- 9 files changed, 93 insertions(+), 40 deletions(-) diff --git a/src/common/singletonpolicies.hpp b/src/common/singletonpolicies.hpp index 5f5624990..3093d275d 100644 --- a/src/common/singletonpolicies.hpp +++ b/src/common/singletonpolicies.hpp @@ -47,7 +47,7 @@ namespace cinelerra /* == several Policies usable in conjunction with cinelerra::Singleton == */ /** - * Policy for creating the Singleton instance statically + * Policy placing the Singleton instance into a statically allocated buffer */ template struct StaticCreate diff --git a/src/nobugcfg.h b/src/nobugcfg.h index c16a569c0..7907d50a1 100644 --- a/src/nobugcfg.h +++ b/src/nobugcfg.h @@ -49,6 +49,7 @@ /* declare flags used throughout the code base... */ NOBUG_DECLARE_FLAG(config); + NOBUG_DECLARE_FLAG(oper); NOBUG_DECLARE_FLAG(test); NOBUG_DECLARE_FLAG(singleton); NOBUG_DECLARE_FLAG(assetmem); @@ -76,6 +77,7 @@ /* flags used throughout the code base... */ NOBUG_CPP_DEFINE_FLAG(config); + NOBUG_CPP_DEFINE_FLAG(oper); NOBUG_CPP_DEFINE_FLAG(test); NOBUG_CPP_DEFINE_FLAG_LIMIT(singleton, LOG_WARNING); NOBUG_CPP_DEFINE_FLAG_LIMIT(assetmem, LOG_WARNING); diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index ec75d84b3..901f21d4e 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -108,16 +108,21 @@ namespace asset other->unlink (this->id); } - /** release all links to other Asset objects held internally. */ + /** release all links to other dependant + * asset objects held internally and advise all parent + * assets to do so with the link to this asset. + * @note we don't release upward links to parent assets, + * thus effectively keeping the parents alive, because + * frequently these accessible parent assets are part + * of our own contract. (e.g. media for clip assets) + */ void Asset::unlink () { - function unregister_me = bind(&Asset::unregister, this,_1); + function forget_me = bind(&Asset::unregister, this,_1); - for_each (parents, unregister_me); - for_each (dependants, unregister_me); + for_each (parents, forget_me); dependants.clear(); - parents.clear(); } /** variant dropping only the links to the given Asset */ diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index 0c304a5de..11f18c85a 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -101,6 +101,7 @@ namespace asset operator size_t() const { return hash; } }; + class DB; class Asset; class AssetManager; typedef const ID& IDA; @@ -246,6 +247,7 @@ namespace asset virtual void defineDependency (PAsset parent); friend class AssetManager; + friend class DB; private: void unregister (PAsset& other); diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index d2fd0d02f..78352680a 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -26,6 +26,7 @@ #include "proc/asset.hpp" +#include "common/error.hpp" #include #include @@ -83,8 +84,8 @@ namespace asset { IdHashtable table; - DB () : table() {} - ~DB () {} + DB () : table() { } + ~DB () {clear();} friend class cinelerra::singleton::StaticCreate; @@ -92,7 +93,8 @@ namespace asset public: template void put (ID hash, shared_ptr& ptr) { table[hash] = static_pointer_cast (ptr); } - void put (ID hash, PAsset& ptr) { table[hash] = ptr; } + void put (ID hash, PAsset& ptr) { table[hash] = ptr; } + bool del (ID hash) { return table.erase (hash); } template shared_ptr @@ -101,6 +103,30 @@ namespace asset return dynamic_pointer_cast (find (hash)); } + /** removes all registered assets and invokes + * Asset::unlink() on each to break cyclic dependencies + */ + void + clear () throw() + { + try + { + IdHashtable::const_iterator i = table.begin(); + IdHashtable::const_iterator e = table.end(); + for ( ; i!=e ; ++i ) + i->second->unlink(); + + table.clear(); + } + catch (cinelerra::Error& EX) + { + WARN (oper, "Problems while clearing Asset registry: %s", EX.what()); + } + catch (...) + { + ERROR (oper, "Serious trouble while clearing Asset registry."); + } } + /** intended for diagnostics */ void diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index 5fa4183f2..617d45f46 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -34,6 +34,7 @@ #include using std::tr1::static_pointer_cast; +using boost::function; using boost::format; using boost::bind; //using boost::lambda::_1; @@ -186,25 +187,28 @@ namespace asset void - AssetManager::detach_child (PAsset& pA, IDA id) + recursive_call (AssetManager* instance, PAsset& pA) + { + instance->remove (pA->getID()); + } + + function + detach_child_recursively () ///< @return a functor recursively invoking remove(child) { - pA->unlink(id); + return bind( &recursive_call, &AssetManager::instance(), _1 ); } /** - * remove the given asset together with all its dependants from the internal DB + * remove the given asset from the internal DB + * together with all its dependants */ void AssetManager::remove (IDA id) - throw(cinelerra::error::Invalid, - cinelerra::error::State) { - UNIMPLEMENTED ("remove Asset with all dependecies"); - - PAsset pA = getAsset (id); - vector par = pA->getParents(); - boost::function func = bind(&detach_child, _1,id ); - for_each (par, func); // ,boost::lambda::var(id))); + PAsset asset = getAsset (id); + for_each (asset->dependants, detach_child_recursively()); + asset->unlink(); + registry.del(id); } diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index a8500ea0b..01e21447c 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -88,8 +88,7 @@ namespace asset /**remove the given asset from the internal DB. * together with all its dependants */ - void remove (IDA id) throw(cinelerra::error::Invalid, - cinelerra::error::State); + void remove (IDA id) ; /** extract a sorted list of all registered Assets */ list listContent() const; @@ -104,7 +103,7 @@ namespace asset static ID reg (KIND* obj, const Asset::Ident& idi) throw(cinelerra::error::Invalid); - /** deleter function used by the Asset smart pointers to delet Asset objects */ + /** deleter function used by the Asset smart pointers to delete Asset objects */ static void destroy (Asset* aa) { delete aa; } friend Asset::Asset (const Asset::Ident& idi); @@ -113,9 +112,6 @@ namespace asset friend class cinelerra::singleton::StaticCreate; - - private: - static void detach_child (PAsset&, IDA); }; diff --git a/tests/components/proc/asset/dependantassetstest.cpp b/tests/components/proc/asset/dependantassetstest.cpp index 82265a168..b76a209e8 100644 --- a/tests/components/proc/asset/dependantassetstest.cpp +++ b/tests/components/proc/asset/dependantassetstest.cpp @@ -92,25 +92,29 @@ namespace asset PAsset a1 (a1_); PTestA a2_ = TA::create(a1); PAsset a2 (a2_); + PAsset a3 = TA::create(a2); ASSERT (a1 == a2->getParents()[0]); ASSERT (a2 == a1->getDependant()[0]); + ASSERT (a2 == a3->getParents()[0]); + ASSERT (a3 == a2->getDependant()[0]); a2_->call_unlink(); - ASSERT (isnil (a2->getParents())); ASSERT (isnil (a2->getDependant())); - ASSERT (!contains (a1->getDependant(), a2)); // has been propagated + ASSERT (!contains (a1->getDependant(), a2)); // has been propagated up + ASSERT (!isnil (a2->getParents())); + ASSERT (contains (a3->getParents(), a2)); // but up-links remain intact a2_->set_depend(a1); - PAsset a3 = TA::create(a1); + PAsset a4 = TA::create(a1); ASSERT (a1 == a2->getParents()[0]); - ASSERT (a1 == a3->getParents()[0]); + ASSERT (a1 == a4->getParents()[0]); ASSERT (a2 == a1->getDependant()[0]); - ASSERT (a3 == a1->getDependant()[1]); + ASSERT (a4 == a1->getDependant()[1]); - a1_->call_unlink(a3->getID()); - ASSERT (!contains (a1->getDependant(), a3)); // selectively removed + a1_->call_unlink(a4->getID()); + ASSERT (!contains (a1->getDependant(), a4)); // selectively removed ASSERT ( contains (a1->getDependant(), a2)); - ASSERT (a1 == a3->getParents()[0]); // no propagation + ASSERT (a1 == a4->getParents()[0]); // no propagation } diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 83be72225..3ffb052d6 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -1004,7 +1004,7 @@ For this Cinelerra3 design, we could consider making GOP just another raw media &rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
          -
          +
          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 Cinelerra Renderengine, the Builder and the related parts.
           
           * [[Packages, Interfaces and Namespaces|InterfaceNamespaces]]
          @@ -1014,7 +1014,19 @@ For this Cinelerra3 design, we could consider making GOP just another raw media
           * [[Multichannel Media|MultichannelMedia]]
           * [[Editing Operations|EditingOperations]]
           * [[Handling of the current Session|CurrentSession]]
          +* [[collecting Ideas for Implementation Guidelines|ImplementationGuidelines]]
           
          +
          +
          +
          +
          !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.
          +* avoid doing anything non-local during the startup phase or shutdown phase of the application. consequently, allways prefer using an explicit cinelerra::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". 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 inteded to create objects, make the ctor protected and provide a factory member called {{{create}}} instead, returning a smart pointer
          +* 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)
           
          @@ -1411,21 +1423,23 @@ This Design strives to achieve a StrongSeparation between the low-level Structur [[Admin]] <<fullscreen>>
          -
          +
          Problem is: when removing an Asset, all corresponding MObjects need to disappear. This means, besides the obvious ~Ref-Link (MObject referring to an asset) we need backlinks or a sort of registry. And still worse: we need to remove the affected MObject from the object network in the EDL and rebuild the Fixture...
           
           &rarr; for a general design discussion see [[Relation of Clip and Asset|RelationClipAsset]]
           
          -As a //first shot// Ichthyo considers the following approach:
          +//Currently// Ichthyo considers the following approach:
           * all references between MObjects and Assets are implemented as __refcounting__ boost::shared_ptr
           * the opposite direction is also a __strong reference__, effectively keeping the clip-MO alive even if it is no longer in use in the session (note this is a cyclic dependency that needs to be actively broken on deletion). This design decision is based on  logical considerations (&rarr; see "deletions, Model-2" [[here|RelationClipAsset]]). This back-link is implemented by a Placement which is stored internally within the asset::Clip, it is needed for clean deletion of Assets, for GUI search functions and for adding the Clip to the EDL (again after been removed, or multiple times as if cloned).
          -* MObjects and Assets implement an {{{unlink()}}} function releasing the internal links to other entities.
          -* Instead of a delete, we call this unlink() function and let the shared_ptr handle the actual deletion.
          +* MObjects and Assets implement an {{{unlink()}}} function releasing any internal links causing circular dependencies. It is always implemented such as to drop //optional// associations while retaining those associations mandatory for fulfilling the objects contract.
          +* Instead of a delete, we call this unlink() function and let the shared_ptr handle the actual deletion. Thus, even if the object is already unlinked, it is still valid and usable as long as some other entity holds a smart-ptr. An ongoing render process for example can still use a clip asset and the corresponding media asset linked as parent, but this media asset's link to the dependant clip has already been cleared (and the media is no longer registered with the AssetManager of course).
          +* so the back-link from dependant asset up to the parent asset is mandatory for the child asset to be functional, but preferably it should be {{{const}}} (only used for information retrieval)
          +* the whole hierarchy has to be crafted accordingly, but this isn't much of a limitation
           * we don't use a registry, rather we model the real dependencies by individual dependency links. So a MediaAsset gets links to all Clips created from this Asset and by traversing this tree, we can handle the deletion
           * after the deletion, the Fixture needs to be rebuilt.
           * but any render processes still can have pointers to the Asset to be removed, and the shared_ptr will ensure, that the referred objects stay alive as long as needed.
           
          -{{red{to be considered in more detail later}}}
          +{{red{let's see if this approach works...}}}
           
          From 393f0944c15eb6b9b9ead12f890b464255278fb6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 23 Nov 2007 04:37:50 +0100 Subject: [PATCH 20/22] DependantAssets_test now (partially) running --- src/proc/asset/db.hpp | 15 ++- tests/51asset.tests | 3 +- .../proc/asset/dependantassetstest.cpp | 1 + tests/components/proc/asset/testasset.cpp | 123 ++++++++++++++++++ tests/components/proc/asset/testasset.hpp | 39 +----- 5 files changed, 143 insertions(+), 38 deletions(-) create mode 100644 tests/components/proc/asset/testasset.cpp diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index 78352680a..6e8914ec9 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -103,8 +103,15 @@ namespace asset return dynamic_pointer_cast (find (hash)); } - /** removes all registered assets and invokes - * Asset::unlink() on each to break cyclic dependencies + /** removes all registered assets and does something similar + * to Asset::unlink() on each to break cyclic dependencies + * (we can't use the real unlink()-function, because this + * will propagate, including calls to the AssetManager. + * As the destructor of DB needs to call clear(), this + * could result in segfaults. This doesn't seem to be + * a problem, though, because we register and process + * \i all assets and the net effect is just breaking + * any cyclic dependencies) */ void clear () throw() @@ -113,8 +120,8 @@ namespace asset { IdHashtable::const_iterator i = table.begin(); IdHashtable::const_iterator e = table.end(); - for ( ; i!=e ; ++i ) - i->second->unlink(); + for ( ; i!=e ; ++i ) + i->second->dependants.clear(); table.clear(); } diff --git a/tests/51asset.tests b/tests/51asset.tests index 06882dbca..6f8afceee 100644 --- a/tests/51asset.tests +++ b/tests/51asset.tests @@ -24,7 +24,8 @@ PLANNED "DeleteAsset_test" DeleteAsset_test <getParents())); ASSERT (contains (a3->getParents(), a2)); // but up-links remain intact + a2_->call_unlink(a1->getID()); a2_->set_depend(a1); PAsset a4 = TA::create(a1); ASSERT (a1 == a2->getParents()[0]); diff --git a/tests/components/proc/asset/testasset.cpp b/tests/components/proc/asset/testasset.cpp new file mode 100644 index 000000000..e8420c203 --- /dev/null +++ b/tests/components/proc/asset/testasset.cpp @@ -0,0 +1,123 @@ +/* + TestClip - test clip (stub) for checking EDL/Session functionality + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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/asset/testasset.hpp" +#include "proc/assetmanager.hpp" + +using std::tr1::static_pointer_cast; + +namespace asset + { + namespace test + { + + namespace + { + uint counter (0); + + /** @internal helper generating continuosely + * different new asset identities + */ + Asset::Ident + make_new_ident () + { + return Asset::Ident ( str(format("TestAsset.%i") % counter) + , Category (META) + , "test" + , counter++ + ); + } + Asset::Ident + make_new_ident (PAsset& ref) + { + return Asset::Ident ( str(format("%s-TestAsset.%i") % ref->ident.name + % counter) + , ref->ident.category + , "test" + , counter++ + ); + } + } + + + template + TestAsset::TestAsset () + : A(make_new_ident ()) + { }; + + + template + TestAsset::TestAsset (PAsset& pRef) + : A(make_new_ident (pRef)) + { + this->defineDependency(pRef); + }; + + + /** @internal helper for the create()-Functions + * retrieving the smart ptr created automatically + * within AssetManager by the Asset base class ctor + */ + template + shared_ptr > + TestAsset::ptrFromThis () + { + return static_pointer_cast,Asset> + (AssetManager::instance().getAsset (this->id)); + }; + + + + } // namespace test + +} // namespace asset + + + + + /*********************************************************/ + /* explicit template instantiations for some Asset Kinds */ + /*********************************************************/ + +#include "proc/asset/unknown.hpp" + + +namespace asset + { + namespace test + { + + template TestAsset::TestAsset (); + template TestAsset::TestAsset (); + + template TestAsset::TestAsset (PAsset& pRef); + template TestAsset::TestAsset (PAsset& pRef); + + template shared_ptr > TestAsset::ptrFromThis (); + template shared_ptr > TestAsset::ptrFromThis (); + + + + } // namespace test + +} // namespace asset diff --git a/tests/components/proc/asset/testasset.hpp b/tests/components/proc/asset/testasset.hpp index b40ac3a77..551a7d8d9 100644 --- a/tests/components/proc/asset/testasset.hpp +++ b/tests/components/proc/asset/testasset.hpp @@ -41,35 +41,6 @@ namespace asset namespace test { - namespace - { - uint counter (0); - - /** @internal helper generating continuosely - * different new asset identities - */ - Asset::Ident - make_ident () - { - return Asset::Ident ( str(format("TestAsset.%i") % counter) - , Category (META) - , "test" - , counter++ - ); - } - Asset::Ident - make_ident (PAsset& ref) - { - return Asset::Ident ( str(format("%s-TestAsset.%i") % ref->ident.name - % counter) - , ref->ident.category - , "test" - , counter++ - ); - } - } - - /** * Test(mock) asset subclass usable for hijacking a given @@ -81,22 +52,24 @@ namespace asset template class TestAsset : public A { - TestAsset () : A(make_ident ()) { }; - TestAsset (PAsset& pRef) : A(make_ident (pRef)) { this->defineDependency(pRef); }; + TestAsset () ; + TestAsset (PAsset&); ///< declared dependant on the given Asset static void deleter (TestAsset* aa) { delete aa; } public: typedef shared_ptr > PA; - static PA create () { return PA (new TestAsset, &deleter); } - static PA create (PAsset& pRef) { return PA (new TestAsset (pRef), &deleter); } + static PA create () { return (new TestAsset )->ptrFromThis(); } + static PA create (PAsset& pRef) { return (new TestAsset (pRef))->ptrFromThis(); } /* === interesting asset features we want to access for tests === */ void call_unlink () { this->unlink (); } void call_unlink (IDA target) { this->unlink (target); } void set_depend (PAsset parent) { this->defineDependency (parent); } + private: + PA ptrFromThis (); }; From 855d0706d94761cfb9bd5b64b153f3151ea7ef4a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 24 Nov 2007 04:18:54 +0100 Subject: [PATCH 21/22] implemented enabling/disabling of dependant assets, WIP: passes test, but code still needs some cleanup... --- src/proc/asset.cpp | 58 ++++++++++++++++--- src/proc/asset.hpp | 6 +- .../proc/asset/dependantassetstest.cpp | 27 ++++++++- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 901f21d4e..1fb15ce47 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -52,7 +52,7 @@ namespace asset * concrete subclasses are created via specialized Factories */ Asset::Asset (const Ident& idi) - : ident(idi), id(AssetManager::reg (this, idi)) + : ident(idi), id(AssetManager::reg (this, idi)), disabled(false) { TRACE (assetmem, "ctor Asset(id=%lu) : adr=%x %s", size_t(id), this, cStr(this->ident) ); } @@ -77,6 +77,36 @@ namespace asset } + //////////////////////////////////////////////////////////TODO: factor this out as library function + + template + inline bool + and_all (SEQ& coll, Oper predicate) + { + typename SEQ::const_iterator e = coll.end(); + typename SEQ::const_iterator i = coll.begin(); + + while (i!=e && predicate(*i)) ++i; + return i==e; + } + + template + inline const V* + deref (const shared_ptr& ptr) + { + return ptr.get(); + } + + //////////////////////////////////////////////////////////TODO: factor this out as library function + + + bool + all_parents_enabled (const vector& parents) + { + return and_all (parents, bind (&Asset::isActive, + bind (&deref,_1) )); //////////TODO: possibly define an operator-> + } + /** * whether this asset is swithced on and consequently included * in the fixture and participates in rendering. @@ -84,19 +114,29 @@ namespace asset bool Asset::isActive () const { - UNIMPLEMENTED ("enable/disable Assets."); + return !this->disabled + && all_parents_enabled (parents); } - - /** - * change the enablement status of this asset. - * @note the corresponding #isActive predicate may depend - * on the enablement status of parent assets as well. - */ + void + propagate_down (PAsset child, bool on) + { + child->enable(on); + } + + + /**change the enablement status of this asset. */ + bool Asset::enable (bool on) throw(cinelerra::error::State) { - UNIMPLEMENTED ("enable/disable Assets."); + if (on != this->disabled) + return true; + if (on && !all_parents_enabled (parents)) + return false; + disabled = !on; + for_each (dependants, bind (&propagate_down, _1 ,on)); + return true; ////////TODO?? } diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index 11f18c85a..e915067a7 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -215,6 +215,8 @@ namespace asset vector parents; vector dependants; + + bool disabled; @@ -275,8 +277,10 @@ namespace asset /** change the enabled status of this asset. * Note the corresponding #isActive predicate may * depend on the enablement status of parent assets as well + * @return \c false if the state could not be changed + * due to parent objects being disabled */ - void enable (bool on=true) throw(cinelerra::error::State); + bool enable (bool on=true) throw(cinelerra::error::State); }; diff --git a/tests/components/proc/asset/dependantassetstest.cpp b/tests/components/proc/asset/dependantassetstest.cpp index b5bb82671..52611b692 100644 --- a/tests/components/proc/asset/dependantassetstest.cpp +++ b/tests/components/proc/asset/dependantassetstest.cpp @@ -55,7 +55,7 @@ namespace asset checkDependencyMechanics (); checkUnlinking (); TODO ("activate missing testcases"); -/////TODO checkEnablementPropagation (); + checkEnablementPropagation (); /////TODO checkRealAssetDependencyRegistration (); } @@ -125,7 +125,8 @@ namespace asset void checkEnablementPropagation () { PAsset a1 = TA::create(); - PAsset a2 = TA::create(a1); + PTestA a2_= TA::create(a1); + PAsset a2 (a2_); PAsset a3 = TA::create(); // not dependant ASSERT (a1->isActive()); @@ -162,6 +163,28 @@ namespace asset ASSERT (!a1->isActive()); ASSERT (!a2->isActive()); ASSERT (a3->isActive()); + + a1->enable(); + a2_->set_depend(a3); // now add a new parent dependency + a3->enable(false); + ASSERT (a1->isActive()); + ASSERT (!a2->isActive()); // has been propagated via the new dependency + ASSERT (!a3->isActive()); + + a2->enable(true); + ASSERT (a1->isActive()); // no change because one of the parents is disbled + ASSERT (!a2->isActive()); + ASSERT (!a3->isActive()); + a1->enable(false); + ASSERT (!a1->isActive()); + a3->enable(true); + ASSERT (!a1->isActive()); // no propagation because the disabled other parent (a1) + ASSERT (!a2->isActive()); + ASSERT (a3->isActive()); + a1->enable(true); + ASSERT (a1->isActive()); // but now propagation is possible + ASSERT (a2->isActive()); + ASSERT (a3->isActive()); } From 940d6de201099472d4062c195bb0e550f1c8f3ee Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 26 Nov 2007 04:27:27 +0100 Subject: [PATCH 22/22] Asset/Clip now using the dependency relation. DependantAssets_test now complete, finally... --- src/common/util.hpp | 18 ++++++- src/proc/asset.cpp | 51 ++++++++----------- src/proc/asset.hpp | 8 +-- src/proc/asset/clip.cpp | 4 +- src/proc/asset/clip.hpp | 5 +- src/proc/asset/db.hpp | 2 +- src/proc/asset/media.cpp | 5 +- src/proc/asset/media.hpp | 18 +++---- src/proc/asset/preview.cpp | 4 +- src/proc/asset/preview.hpp | 2 +- src/proc/asset/unknown.cpp | 4 +- src/proc/assetmanager.cpp | 6 ++- src/proc/assetmanager.hpp | 2 +- src/proc/mobject/session/clip.cpp | 8 +++ src/proc/mobject/session/clip.hpp | 7 +++ src/proc/mobject/session/mobjectfactory.hpp | 1 - .../proc/asset/assetdiagnostics.hpp | 22 ++++++-- .../proc/asset/dependantassetstest.cpp | 25 +++++---- tests/components/proc/asset/makecliptest.cpp | 15 +----- 19 files changed, 123 insertions(+), 84 deletions(-) diff --git a/src/common/util.hpp b/src/common/util.hpp index 6d5119b14..4857382d6 100644 --- a/src/common/util.hpp +++ b/src/common/util.hpp @@ -96,7 +96,7 @@ namespace util * in any sequencial container */ template inline bool - contains (SEQ& cont, typename SEQ::value_type& val) + contains (SEQ& cont, typename SEQ::const_reference val) { typename SEQ::const_iterator begin = cont.begin(); typename SEQ::const_iterator end = cont.end(); @@ -128,6 +128,22 @@ namespace util } + /** shortcut for testing all elements of a collection + * with the given predicate. + */ + template + inline bool + and_all (SEQ& coll, Oper predicate) + { + typename SEQ::const_iterator e = coll.end(); + typename SEQ::const_iterator i = coll.begin(); + + while (i!=e && predicate(*i)) ++i; + return i==e; + } + + + /** produce an identifier based on the given string. * remove non-standard-chars, reduce sequences of punctuation diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 1fb15ce47..5ca25754e 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -36,6 +36,7 @@ using boost::function; using util::contains; using util::removeall; using util::for_each; +using util::and_all; using util::cStr; @@ -52,7 +53,7 @@ namespace asset * concrete subclasses are created via specialized Factories */ Asset::Asset (const Ident& idi) - : ident(idi), id(AssetManager::reg (this, idi)), disabled(false) + : ident(idi), id(AssetManager::reg (this, idi)), enabled(true) { TRACE (assetmem, "ctor Asset(id=%lu) : adr=%x %s", size_t(id), this, cStr(this->ident) ); } @@ -76,35 +77,18 @@ namespace asset return str (id_tuple % ident.name % ident.category % ident.org % ident.version); } - - //////////////////////////////////////////////////////////TODO: factor this out as library function - template - inline bool - and_all (SEQ& coll, Oper predicate) - { - typename SEQ::const_iterator e = coll.end(); - typename SEQ::const_iterator i = coll.begin(); - - while (i!=e && predicate(*i)) ++i; - return i==e; - } - template - inline const V* - deref (const shared_ptr& ptr) - { - return ptr.get(); - } - - //////////////////////////////////////////////////////////TODO: factor this out as library function + function check_isActive + = bind ( &Asset::isActive + , bind (&PAsset::get, _1 ) + ); bool all_parents_enabled (const vector& parents) { - return and_all (parents, bind (&Asset::isActive, - bind (&deref,_1) )); //////////TODO: possibly define an operator-> + return and_all (parents, check_isActive); } /** @@ -114,29 +98,30 @@ namespace asset bool Asset::isActive () const { - return !this->disabled + return this->enabled && all_parents_enabled (parents); } - + void propagate_down (PAsset child, bool on) { child->enable(on); } - /**change the enablement status of this asset. */ bool Asset::enable (bool on) throw(cinelerra::error::State) { - if (on != this->disabled) + if (on == this->enabled) return true; if (on && !all_parents_enabled (parents)) return false; - disabled = !on; + + // can indeed to do the toggle... + this->enabled = on; for_each (dependants, bind (&propagate_down, _1 ,on)); - return true; ////////TODO?? + return true; } @@ -184,6 +169,14 @@ namespace asset parents.push_back (parent); parent->dependants.push_back(p_this); } + + void + Asset::defineDependency (Asset& parent) + { + PAsset p_parent (AssetManager::getPtr(parent)); + ASSERT (p_parent); + defineDependency (p_parent); + } } // namespace asset diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index e915067a7..4173cf31b 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -106,6 +106,7 @@ namespace asset class AssetManager; typedef const ID& IDA; typedef shared_ptr PAsset; + typedef shared_ptr PcAsset; @@ -216,7 +217,7 @@ namespace asset vector parents; vector dependants; - bool disabled; + bool enabled; @@ -246,7 +247,8 @@ namespace asset /** establish a connection between this and the given parent asset, * denoting we are in some way dependant on the parent. */ - virtual void defineDependency (PAsset parent); + void defineDependency (PAsset parent); + void defineDependency (Asset& parent); friend class AssetManager; friend class DB; @@ -307,7 +309,7 @@ namespace asset /** convienient for debugging */ - inline string str (const PAsset& a) + inline string str (PcAsset& a) { if (a) return string (*a.get()); diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp index 4de320bf4..1fee2b091 100644 --- a/src/proc/asset/clip.cpp +++ b/src/proc/asset/clip.cpp @@ -59,14 +59,14 @@ namespace asset - Clip::Clip (const Media& mediaref) + Clip::Clip (Media& mediaref) : Media (createClipIdent (mediaref), mediaref.getFilename(), mediaref.getLength()) , source_ (mediaref) , clipMO_ (createClipMO (*this, source_)) { - + this->defineDependency (mediaref); } diff --git a/src/proc/asset/clip.hpp b/src/proc/asset/clip.hpp index 80392f290..142f73fdc 100644 --- a/src/proc/asset/clip.hpp +++ b/src/proc/asset/clip.hpp @@ -38,15 +38,14 @@ namespace asset /** media source of this clip */ const Media& source_; - /** the corresponding (dependant) clip-MO - * @todo seems to be obsolete by the reworked design of multichannel media 11/07 */ + /** the corresponding (dependant) clip-MO */ PClipMO clipMO_; public: virtual PClipMO createClip () const; protected: - Clip (const Media& mediaref); + Clip (Media& mediaref); friend class MediaFactory; virtual PClip getClipAsset (); diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index 6e8914ec9..c0ba4b19f 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -137,7 +137,7 @@ namespace asset /** intended for diagnostics */ void - asList (list& output) const + asList (list& output) const { IdHashtable::const_iterator i = table.begin(); IdHashtable::const_iterator e = table.end(); diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index 6d61d7004..05f4417ad 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -213,12 +213,13 @@ namespace asset /** Factory method for creating a Clip asset based * on the given Media asset. This asset::Clip can be used * to create clip in the EDL covering the whole length of - * this media. + * this media. + * @note creates a dependency between media and new clip * @throw Invalid if the given media asset is not top-level, * but rather part or a multichannel (compound) media */ shared_ptr - MediaFactory::operator() (const asset::Media& mediaref) throw(cinelerra::error::Invalid) + MediaFactory::operator() (asset::Media& mediaref) throw(cinelerra::error::Invalid) { if (mediaref.checkCompound()) throw cinelerra::error::Invalid (str(format("Attempt to create a asset::Clip from the media %s, " diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index defaf51b2..3ba17ec52 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -73,7 +73,7 @@ namespace asset public: typedef shared_ptr PMedia; - typedef shared_ptr PClip; + typedef shared_ptr PClip; typedef shared_ptr PProcPatt; typedef mobject::session::PClipMO PClipMO; @@ -86,6 +86,13 @@ namespace asset return static_cast& > (Asset::getID()); } + /** Service Access Point for getting a processing template + * describing how to build the render nodes network + * necessary for this Media or Clip. This includes + * Codecs and postprocessing (stretching, deinterlacing...) + */ + PProcPatt howtoProc () const; + /** Service Access Point for creating a Clip entity usable within * the EDL/Session from a given Media or Clip Asset. As a sideeffect, * a corresponding asset::Clip is created as well if necessary. @@ -95,13 +102,6 @@ namespace asset */ PClipMO createClip (); - /** Service Access Point for getting a processing template - * describing how to build the render nodes network - * necessary for this Media or Clip. This includes - * Codecs and postprocessing (stretching, deinterlacing...) - */ - PProcPatt howtoProc () const; - /** @return the overall length of the media represented by this asset */ virtual Time getLength () const; @@ -151,7 +151,7 @@ namespace asset PType operator() (const char* file, asset::Kind); shared_ptr - operator() (const asset::Media& mediaref) throw(cinelerra::error::Invalid); + operator() (asset::Media& mediaref) throw(cinelerra::error::Invalid); }; diff --git a/src/proc/asset/preview.cpp b/src/proc/asset/preview.cpp index d626d7525..e2a920d57 100644 --- a/src/proc/asset/preview.cpp +++ b/src/proc/asset/preview.cpp @@ -52,12 +52,14 @@ namespace asset /** create a preview placeholder ("proxy media") for the given * media asset. The name of the created media asset is derived * by decorating the original media's name. + * @note creates a dependency between the media and this proxy */ - Preview::Preview (const Media& mediaref) + Preview::Preview (Media& mediaref) : Unknown (createProxyIdent (mediaref.ident), mediaref.getFilename(), mediaref.getLength()) { + this->defineDependency (mediaref); UNIMPLEMENTED ("do something to setup proxy media"); } diff --git a/src/proc/asset/preview.hpp b/src/proc/asset/preview.hpp index 0d2176b5e..462e9149d 100644 --- a/src/proc/asset/preview.hpp +++ b/src/proc/asset/preview.hpp @@ -38,7 +38,7 @@ namespace asset class Preview : public Unknown { protected: - Preview (const Media& mediaref); + Preview (Media& mediaref); friend class MediaFactory; }; diff --git a/src/proc/asset/unknown.cpp b/src/proc/asset/unknown.cpp index 3e3620cdc..48194d878 100644 --- a/src/proc/asset/unknown.cpp +++ b/src/proc/asset/unknown.cpp @@ -34,7 +34,9 @@ namespace asset /** create a placeholder for a media with the given identity. * the denoted original media (identity) can be accessed later - * on using the Unknown::getOrg() function */ + * on using the Unknown::getOrg() function. + * @note we don't depend on the refered media... + */ Unknown::Unknown (const Asset::Ident& idi, string name, Time length) : Media (idi, name, length) { diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index 617d45f46..c59354cf2 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -213,10 +213,10 @@ namespace asset - list + list AssetManager::listContent() const { - list res; + list res; registry.asList (res); res.sort(); return res; @@ -233,6 +233,7 @@ namespace asset /************************************************************/ #include "proc/asset/media.hpp" +#include "proc/asset/clip.hpp" #include "proc/asset/proc.hpp" #include "proc/asset/struct.hpp" #include "proc/asset/meta.hpp" @@ -252,6 +253,7 @@ namespace asset template shared_ptr AssetManager::getPtr (const Asset& asset); template shared_ptr AssetManager::getPtr (const Media& asset); + template shared_ptr AssetManager::getPtr (const Clip& asset); } // namespace asset diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 01e21447c..71988cd0d 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -91,7 +91,7 @@ namespace asset void remove (IDA id) ; /** extract a sorted list of all registered Assets */ - list listContent() const; + list listContent() const; diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp index 68333f36e..0ce3894ae 100644 --- a/src/proc/mobject/session/clip.cpp +++ b/src/proc/mobject/session/clip.cpp @@ -68,6 +68,14 @@ namespace mobject { return asset::AssetManager::getPtr (mediaDef_); } + + + PClipAsset + Clip::findClipAsset () const + { + return asset::AssetManager::getPtr (clipDef_); + } + diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index 0843de9d5..a4e0c7271 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -39,6 +39,7 @@ namespace mobject { using asset::Media; typedef shared_ptr PMedia; + typedef shared_ptr PClipAsset; /** @@ -74,6 +75,12 @@ namespace mobject /** access the underlying media asset */ PMedia getMedia () const; + /** locate the corresponding asset + * representing this clip or the whole + * compound in case of a multichannel clip + */ + PClipAsset findClipAsset () const; + }; typedef Placement PClipMO; diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index aeb267f3a..e8fe05794 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -43,7 +43,6 @@ namespace mobject class Clip; class Effect; - typedef shared_ptr PClipAsset; class MObjectFactory { diff --git a/tests/components/proc/asset/assetdiagnostics.hpp b/tests/components/proc/asset/assetdiagnostics.hpp index 3fcd89c7a..e4147f3a4 100644 --- a/tests/components/proc/asset/assetdiagnostics.hpp +++ b/tests/components/proc/asset/assetdiagnostics.hpp @@ -40,6 +40,7 @@ #include #include +using util::contains; using util::for_each; using boost::format; using boost::bind; @@ -50,7 +51,8 @@ using std::cout; namespace asset { - inline void dump (const PAsset& aa) + inline void + dump (PcAsset& aa) { if (!aa) cout << "Asset(NULL)\n"; @@ -60,12 +62,26 @@ namespace asset cout << fmt % str(aa) % aa->getID() % aa.get() % &aa % (aa.use_count() - 1) << "\n"; } } - inline void dumpAssetManager () + inline void + dumpAssetManager () { - list assets (AssetManager::instance().listContent()); + list assets (AssetManager::instance().listContent()); cout << "----all-registered-Assets----\n"; for_each (assets, bind (&dump, _1)); } + + + template + inline bool + dependencyCheck (C child, P parent) + { + return (child == parent) + || (0 < child->getParents().size() + && (parent == child->getParents()[0]) + && (contains (parent->getDependant(), child))); + ; + } + diff --git a/tests/components/proc/asset/dependantassetstest.cpp b/tests/components/proc/asset/dependantassetstest.cpp index 52611b692..49c5510a2 100644 --- a/tests/components/proc/asset/dependantassetstest.cpp +++ b/tests/components/proc/asset/dependantassetstest.cpp @@ -23,15 +23,14 @@ #include "common/test/run.hpp" #include "proc/asset/testasset.hpp" +#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/media.hpp" +#include "proc/asset/clip.hpp" #include "common/util.hpp" -//#include -#include - -using util::isnil; using util::contains; -//using boost::format; -using std::string; +using util::isnil; + namespace asset @@ -54,13 +53,13 @@ namespace asset { checkDependencyMechanics (); checkUnlinking (); - TODO ("activate missing testcases"); checkEnablementPropagation (); -/////TODO checkRealAssetDependencyRegistration (); + checkRealAssetDependencyRegistration (); } typedef TestAsset TA; typedef TA::PA PTestA; + /** @test check operation of basic asset dependency support */ @@ -74,8 +73,6 @@ namespace asset ASSERT (a1 == a2->getParents()[0]); // TestAsset registered a1 as parent ASSERT (a2 == a1->getDependant()[0]); - TRACE(test, "a1.cnt=%i",a1.use_count()); - TRACE(test, "a2.cnt=%i",a2.use_count()); PAsset a3 = TA::create(); a2->set_depend(a3); ASSERT (a3 == a2->getParents()[1]); @@ -196,7 +193,13 @@ namespace asset */ void checkRealAssetDependencyRegistration () { - UNIMPLEMENTED ("handling of Asset dependencies"); + // -----Media and Clip-------------------------------- + typedef Media::PMedia PM; + typedef Media::PClip PC; + PM mm = asset::Media::create("test-1", VIDEO); + PC cc = mm->createClip()->findClipAsset(); + ASSERT (dependencyCheck (cc,mm)); + } }; diff --git a/tests/components/proc/asset/makecliptest.cpp b/tests/components/proc/asset/makecliptest.cpp index 55c8e8376..5ec6a76bc 100644 --- a/tests/components/proc/asset/makecliptest.cpp +++ b/tests/components/proc/asset/makecliptest.cpp @@ -27,8 +27,7 @@ #include "proc/assetmanager.hpp" #include "proc/asset/media.hpp" #include "proc/mobject/session/clip.hpp" - -//#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/assetdiagnostics.hpp" using util::contains; using util::isnil; @@ -68,22 +67,12 @@ namespace asset TODO ("implement Processing Pattern!!!"); // ASSERT (cm->howtoProc() == mm->howtoProc()); ASSERT (cm->ident.org == mm->ident.org); - ASSERT (dependencyCheck (mm,cm)); + ASSERT (dependencyCheck (cm,mm)); TRACE (assetmem, "leaving MakeClip_test::run()"); TRACE (mobjectmem, "leaving MakeClip_test::run()"); } - bool dependencyCheck (PM media, PM clip) - { - TODO ("check asset dependencies, when this feature is implemented"); - return true; //TODO - - return (0 < clip->getParents().size()) - && (media == clip->getParents()[0]) -// && (contains (media->getDependant(), clip)); //TODO implement Asset dependecies - ; - } };