2007-08-08 04:50:02 +02:00
/*
PLACEMENT . hpp - Key Abstraction : a way to place and locate a Media Object
2010-12-17 23:28:49 +01:00
2008-03-10 04:25:03 +01:00
Copyright ( C ) Lumiera . org
2008 , Hermann Vosseler < Ichthyostega @ web . de >
2010-12-17 23:28:49 +01:00
2007-08-08 04:50:02 +02:00
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License as
2010-12-17 23:28:49 +01:00
published by the Free Software Foundation ; either version 2 of
the License , or ( at your option ) any later version .
2007-08-08 04:50:02 +02:00
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 .
2010-12-17 23:28:49 +01:00
2007-08-08 04:50:02 +02:00
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 0213 9 , USA .
2010-12-17 23:28:49 +01:00
2007-08-08 04:50:02 +02:00
*/
2007-10-18 17:29:01 +02:00
/** @file placement.hpp
* * Placements are at the very core of all editing operations ,
2007-10-19 06:39:52 +02:00
* * because they act as handles to access the media objects to be manipulated .
2010-02-22 03:52:52 +01:00
* * Moreover , Placements are the actual " content " of the Session and Fixture and thus
2009-05-29 07:10:54 +02:00
* * are small handle like objects . Many editing tasks include locating some Placement
* * within the Session or directly take a ref to a Placement .
2007-10-18 17:29:01 +02:00
* *
2007-10-19 06:39:52 +02:00
* * Placements are < b > refcounting smart pointers < / b > : 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
2010-02-22 03:52:52 +01:00
* * supposed to be located within the Session or Fixture . The way in which this placing happens
2009-05-09 03:08:38 +02:00
* * is controlled and parametrised by a collection ( chain ) of LocatingPin objects . By adding
2007-10-19 06:39:52 +02:00
* * 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
2015-05-31 02:03:24 +02:00
* * absolute position ( time , output ) .
2007-10-18 17:29:01 +02:00
* *
2009-05-29 07:10:54 +02:00
* * Together , this yields semantics somewhere in between value semantics and reference semantics .
2010-01-08 03:59:01 +01:00
* * As any smart - ptr , placements are copyable , but each such copy takes on a < i > distinct identity . < / i >
* * Moreover , when added to the Session , a placement acts as if it was an \ em instance of the object
* * it points at , with the purpose to bind this instance into the Session with specific placement
2009-05-29 07:10:54 +02:00
* * properties . Thus , such a placement - within - session \ em is an distinguishable entity , because
* * the settings on the contained LocatingPin chain \ em do constitute the relation properties
* * of the MObject " placed " by this placement . To support this rather ref - like semantics , any
2010-01-08 03:59:01 +01:00
* * placement has an embedded ID ( identity ) . Building on this ID , it is possible to create a
* * smart - ptr like PlacementRef to denote a specific placement found within the Session .
2009-05-29 07:10:54 +02:00
* *
2007-10-18 17:29:01 +02:00
* * Placements are templated on the type of the actual MObject they refer to , so , sometimes
2010-01-08 03:59:01 +01:00
* * e . g . we rather use a Placement < Clip > to be able to use the more specific methods of the
2007-10-18 17:29:01 +02:00
* * session : : Clip interface . But < i > please note the following detail : < / i > this type
2009-05-09 03:08:38 +02:00
* * labelling and downcasting is the < i > only < / i > difference between these subclasses ,
2007-10-19 06:39:52 +02:00
* * besides that , they can be replaced literally by one another ( slicing is accepted ) .
2007-10-18 17:29:01 +02:00
* *
* * @ see ExplicitPlacement
2007-10-19 06:39:52 +02:00
* * @ see LocatingPin interface for controlling the positioning parameters
2007-10-18 17:29:01 +02:00
* *
*/
2007-08-09 18:51:47 +02:00
# ifndef MOBJECT_PLACEMENT_H
# define MOBJECT_PLACEMENT_H
2007-08-08 04:50:02 +02:00
2011-12-01 23:32:34 +01:00
# include "lib/error.hpp"
2009-05-29 07:10:54 +02:00
# include "lib/hash-indexed.hpp"
2011-05-16 08:37:36 +02:00
# include "lib/time/timevalue.hpp"
2007-10-18 17:29:01 +02:00
# include "proc/mobject/session/locatingpin.hpp"
2009-05-29 07:10:54 +02:00
2010-01-08 04:00:14 +01:00
# include "proc/asset/pipe.hpp" //////////////TICKET #109 : get rid of this
2007-08-08 04:50:02 +02:00
2014-04-03 22:42:48 +02:00
# include <memory>
2007-10-19 06:39:52 +02:00
2007-08-08 04:50:02 +02:00
2011-12-02 16:10:03 +01:00
namespace proc {
2009-05-09 03:08:38 +02:00
namespace mobject {
2007-11-12 02:05:39 +01:00
namespace session { class MObjectFactory ; }
2009-05-09 03:08:38 +02:00
2009-05-29 07:10:54 +02:00
class MObject ;
2007-08-09 18:51:47 +02:00
class ExplicitPlacement ;
2007-11-12 02:05:39 +01:00
2014-04-03 22:42:48 +02:00
using std : : shared_ptr ;
using std : : static_pointer_cast ;
2009-05-29 07:10:54 +02:00
using lib : : HashIndexed ;
2009-05-09 03:08:38 +02:00
2007-10-19 06:39:52 +02:00
2007-11-12 02:05:39 +01:00
2007-10-22 05:15:08 +02:00
/**
* A refcounting Handle to an MObject of type MO ,
2009-05-29 07:10:54 +02:00
* used to constrain or explicitly specify the location
2010-02-22 03:52:52 +01:00
* where the MObject is supposed to be within the Session / Model .
2009-05-29 07:10:54 +02:00
* Placements are copyable ( like values ) , but may be distinguished
* by their identity ( reference semantics ) , which is based on an
* \ link lib : : HashIndexed hash - ID \ endlink .
*
* Placements are defined to form a hierarchy , thereby mirroring
* the relations between their referents to some degree . This allows
* for building APIs targeted at specific kinds of MObjects , and
* at the same time allows a specific placement to stand - in when
* just a unspecific Placement < MObject > is required .
*
* @ param MO the ( compile time ) type of the referent
* @ param B immediate base class of this placement
*/
template < class MO , class B = MObject >
class Placement ;
/**
* this specialisation forms the root of all placements
* and defines all of Placement ' s actual functionality .
2007-10-22 05:15:08 +02:00
*/
2009-05-29 07:10:54 +02:00
template < >
class Placement < MObject , MObject >
2010-01-08 04:00:14 +01:00
: protected shared_ptr < MObject >
, public HashIndexed < Placement < MObject > , lib : : hash : : LuidH >
2007-08-08 04:50:02 +02:00
{
2007-08-09 18:51:47 +02:00
protected :
2009-06-09 09:05:19 +02:00
typedef HashIndexed < Placement < MObject > , lib : : hash : : LuidH > HashInd ;
2009-05-29 07:10:54 +02:00
typedef shared_ptr < MObject > _SmartPtr ;
typedef void ( * Deleter ) ( MObject * ) ;
2011-05-16 08:37:36 +02:00
typedef lib : : time : : Time Time ;
2010-01-08 04:00:14 +01:00
typedef asset : : shared_ptr < asset : : Pipe > Pipe ; ////TICKET #109 : get rid of this
2008-01-07 18:16:03 +01:00
2009-05-09 03:08:38 +02:00
2007-08-09 18:51:47 +02:00
public :
2007-10-19 06:39:52 +02:00
/** smart pointer: accessing the MObject,
* which is subject to placement .
* @ note we don ' t provide operator *
*/
2009-05-31 05:02:03 +02:00
MObject *
2007-10-19 06:39:52 +02:00
operator - > ( ) const
{
2007-11-12 02:05:39 +01:00
ENSURE ( * this ) ;
2009-05-29 07:10:54 +02:00
return _SmartPtr : : operator - > ( ) ;
2009-06-06 04:02:08 +02:00
}
/** run time diagnostics: is the pointee
* of this placement compatible to the given type ?
*/
template < class Y >
bool
isCompatible ( ) const
{
2009-06-09 09:05:19 +02:00
return 0 ! = dynamic_cast < Y * > ( get ( ) ) ;
2009-06-06 04:02:08 +02:00
}
2010-01-13 04:38:12 +01:00
/** extend shared ownership to the given smart-ptr
* @ note never throws
*/
template < class Y >
void
extendOwnershipTo ( shared_ptr < Y > & target ) const
{
REQUIRE ( isCompatible < Y > ( ) ) ;
target = static_pointer_cast < Y > ( * this ) ;
}
2010-03-07 06:29:03 +01:00
/** free function to detect two placements sharing a pointee */
friend bool
isSharedPointee ( Placement const & p1 , Placement const & p2 )
{
return static_cast < const void * > ( p1 . get ( ) )
= = static_cast < const void * > ( p2 . get ( ) ) ;
}
2007-09-27 04:45:06 +02:00
2008-05-19 08:46:19 +02:00
operator string ( ) const ;
2009-05-29 07:10:54 +02:00
size_t use_count ( ) const { return _SmartPtr : : use_count ( ) ; }
2009-06-09 09:05:19 +02:00
bool isValid ( ) const { return _SmartPtr : : use_count ( ) ; }
2008-05-19 08:46:19 +02:00
2007-11-14 10:10:52 +01:00
virtual ~ Placement ( ) { } ;
2007-12-22 08:45:09 +01:00
2009-05-09 03:08:38 +02:00
2007-10-19 22:34:07 +02:00
2007-10-19 06:39:52 +02:00
/** interface for defining the kind of placement
2009-05-21 04:06:36 +02:00
* to employ , and for controlling any additional
2007-10-19 06:39:52 +02:00
* constraints and properties .
*/
session : : LocatingPin chain ;
/** combine and resolve all constraints defined
* by the various LocatingPin ( \ see # chain ) and
2007-08-09 18:51:47 +02:00
* provide the resulting ( explicit ) placement .
*/
2007-11-12 02:05:39 +01:00
virtual ExplicitPlacement resolve ( ) const ;
2009-11-27 20:30:06 +01:00
//////////////////////////TODO (1) could resolve() return a reference? Otherwise placement-ref.hpp needs to include ExplicitPlacement
//////////////////////////TODO (2) does this really need to be virtual. Guess not. It's not abstract and not really polymorphic. But virtual here causes template bloat.
////////////TICKET #439
2007-10-19 06:39:52 +02:00
2007-09-27 04:45:06 +02:00
2010-01-08 04:00:14 +01:00
Placement ( Placement const & ref )
: _SmartPtr ( ref )
, HashInd ( ) // creating a new ID!
, chain ( ref . chain )
{ }
2007-09-27 04:45:06 +02:00
protected :
2009-05-29 07:10:54 +02:00
Placement ( MObject & subject , Deleter killer )
2010-01-08 04:00:14 +01:00
: _SmartPtr ( & subject , killer ) { } ;
2007-11-12 02:05:39 +01:00
friend class session : : MObjectFactory ;
2010-01-08 04:00:14 +01:00
/////////////////////////////////////////////////////////TICKET #513
// private:
// /** copy assignment prohibited */
// Placement& operator= (Placement const&);
/////////////////////////////////////////////////////////TICKET #513
2007-10-18 17:29:01 +02:00
} ;
2009-05-29 07:10:54 +02:00
/**
* any specific placements are supposed to be derived
* from Placement < MObject > , or an intermediary interface ,
* in case the second template parameter is used .
* @ note please refrain from adding additional functionality
* to these subclasses . Especially , don ' t add any fields
* to the subclass , as Placements are treated like values
* at times , and thus slicing will happen , which in this
* special case is acceptable .
*/
template < class MO , class B >
class Placement
: public Placement < B >
{
protected :
typedef Placement < B > _Parent ;
2009-11-27 20:30:06 +01:00
typedef typename _Parent : : template Id < MO > const & _Id ;
2009-05-29 07:10:54 +02:00
typedef typename _Parent : : Deleter Deleter ;
typedef typename _Parent : : _SmartPtr _SmartPtr ;
Placement ( MO & mo , Deleter killer )
: _Parent ( mo , killer )
{ } ;
friend class session : : MObjectFactory ;
public :
2009-05-31 05:02:03 +02:00
MO *
2009-05-29 07:10:54 +02:00
operator - > ( ) const
{
ENSURE ( INSTANCEOF ( MO , this - > get ( ) ) ) ;
return static_cast < MO * >
( _SmartPtr : : operator - > ( ) ) ;
}
2009-06-09 09:05:19 +02:00
2009-11-27 20:30:06 +01:00
_Id
2009-06-09 09:05:19 +02:00
getID ( ) const ///< @note overrides HashIndexed::getID to pass specific type information,
{
return _Parent : : template recastID < MO > ( ) ;
}
2009-05-29 07:10:54 +02:00
} ;
2007-10-19 06:39:52 +02:00
2007-09-27 04:45:06 +02:00
2009-11-13 16:32:22 +01:00
/** @todo cleanup uses of ref-to-placement. See Ticket #115 */
2009-06-09 09:05:19 +02:00
typedef Placement < MObject > PlacementMO ;
2010-01-14 22:46:27 +01:00
//‘ typedef class mobject::Placement<mobject::MObject, mobject::MObject> mobject::PlacementMO’
2009-05-29 07:10:54 +02:00
typedef Placement < MObject > PMO ;
2010-01-09 04:46:17 +01:00
/* == free functions == */
2007-08-09 18:51:47 +02:00
2010-01-09 04:46:17 +01:00
string
format_PlacementID ( PlacementMO const & ) ;
/** compare the properties of placement
* @ return \ c true if all the LocatingPin entries
* in both placements are semantically equivalent .
*/
bool
isSameDef ( PlacementMO const & , PlacementMO const & ) ;
2011-12-02 16:10:03 +01:00
} } // namespace proc::mobject
2007-08-08 04:50:02 +02:00
# endif