From d7e7d3d613160de3baeadcd292c61c28a1e2dcf9 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 19 Oct 2007 06:39:52 +0200 Subject: [PATCH] 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