fixing, stubbing, and some chainsaw surgery to get half-finished code through the compiler
This commit is contained in:
parent
3a7de1654a
commit
102e96891b
24 changed files with 817 additions and 626 deletions
|
|
@ -108,7 +108,7 @@ namespace lib {
|
|||
bool operator!= (LuidH const& o) const { return !operator== (o); }
|
||||
|
||||
/** for passing to C APIs */
|
||||
LUID get() { return &luid_; }
|
||||
LUID get() const { return (LUID)&luid_; }
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -172,6 +172,15 @@ namespace lib {
|
|||
return id_;
|
||||
}
|
||||
|
||||
/** redefining of the specific type info of the Id is allowed,
|
||||
* as all share the same implementation */
|
||||
template<typename T>
|
||||
Id<T> const&
|
||||
recastID () const
|
||||
{
|
||||
return reinterpret_cast<Id<T> const&> (getID());
|
||||
}
|
||||
|
||||
void
|
||||
assignID (HashIndexed const& ref)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
namespace control {
|
||||
|
||||
using lumiera::Symbol;
|
||||
// using lumiera::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace mobject {
|
||||
|
||||
|
||||
|
||||
|
|
@ -63,11 +62,11 @@ namespace mobject
|
|||
|
||||
|
||||
protected:
|
||||
/* @todo ichthyo considers a much more elegant implementation utilizing a subclass
|
||||
/* @todo ichthyo considers a much more elegant implementation utilising 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)
|
||||
* be initialised directly here in the ExplicitPlacement ctor.
|
||||
* (ichthyo: see Trac #100)
|
||||
*/
|
||||
ExplicitPlacement (const Placement<MObject>& base, const SolutionData found)
|
||||
: Placement<MObject>(base),
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ namespace mobject {
|
|||
/** */
|
||||
|
||||
|
||||
LUMIERA_ERROR_DEFINE (INVALID_PLACEMENTREF, "unresolvable placement reference, or of incompatible type");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64,8 +64,11 @@ namespace mobject {
|
|||
class MORef
|
||||
: public lib::Handle<MO>
|
||||
{
|
||||
PlacementRef<MO> pRef_;
|
||||
typedef lib::Handle<MO> _Par;
|
||||
|
||||
PlacementRef<MO> pRef_; ////////////////////////////////////////////////////////////////////TODO: how to create an "inactive" PlacementRef???
|
||||
|
||||
using _Par::smPtr_;
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -74,7 +77,7 @@ namespace mobject {
|
|||
{
|
||||
REQUIRE (smPtr_.get(), "Lifecycle-Error");
|
||||
ENSURE (INSTANCEOF (MO, smPtr_.get()));
|
||||
return smPtr_::operator-> ();
|
||||
return smPtr_.operator-> ();
|
||||
}
|
||||
|
||||
Placement<MO>& getPlacement();
|
||||
|
|
|
|||
|
|
@ -65,6 +65,18 @@ namespace mobject {
|
|||
typedef PlacementIndex::ID ID;
|
||||
|
||||
|
||||
/** @internal Factory for creating a new placement index.
|
||||
* For use by the Session and for unit tests.
|
||||
*/
|
||||
PlacementIndex::Factory PlacementIndex::create;
|
||||
|
||||
PlacementIndex::PlacementIndex()
|
||||
: pTab_()
|
||||
{ }
|
||||
|
||||
PlacementIndex::~PlacementIndex() { }
|
||||
|
||||
|
||||
PlacementMO&
|
||||
PlacementIndex::getRoot() const
|
||||
{
|
||||
|
|
@ -80,18 +92,54 @@ namespace mobject {
|
|||
|
||||
|
||||
bool
|
||||
PlacementIndex::contains (PlacementMO&) const
|
||||
PlacementIndex::contains (ID id) const
|
||||
{
|
||||
UNIMPLEMENTED ("containment test: is the given Placement known within this index");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PlacementMO&
|
||||
PlacementIndex::find (ID) const
|
||||
{
|
||||
UNIMPLEMENTED ("main operation of PlacmentIndex: lookup a Placement by ID");
|
||||
}
|
||||
|
||||
|
||||
|
||||
PlacementMO&
|
||||
PlacementIndex::getScope (ID) const
|
||||
{
|
||||
UNIMPLEMENTED ("Secondary core operation of PlacmentIndex: find the 'parent' Placement by using the Placement relation index");
|
||||
}
|
||||
|
||||
|
||||
vector<PRef>
|
||||
PlacementIndex::getReferrers (ID) const
|
||||
{
|
||||
UNIMPLEMENTED ("query the Placement relation index and retrieve all other placements bound to this one by a placement-relation");
|
||||
}
|
||||
|
||||
|
||||
ID
|
||||
PlacementIndex::insert (PlacementMO& newObj, PlacementMO& targetScope)
|
||||
{
|
||||
UNIMPLEMENTED ("store a new information record into PlacmentIndex: ID -> (ref-to-Placement, parent-Placement)");
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlacementIndex::remove (ID)
|
||||
{
|
||||
UNIMPLEMENTED ("remove a information record from PlacementIndex, and also deregister any placement-relations bound to it");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
namespace { // implementation detail: default global placement index access
|
||||
|
||||
PIdx globalIndex (0);
|
||||
PIdx globalIndex;
|
||||
|
||||
PIdx const&
|
||||
getGlobalIndex()
|
||||
|
|
@ -105,23 +153,20 @@ namespace mobject {
|
|||
} // (End) implementation detail
|
||||
|
||||
|
||||
/** @internal Factory for creating a new placement index.
|
||||
* For use by the Session and for unit tests.
|
||||
*/
|
||||
PlacementIndex::Factory PlacementIndex::create;
|
||||
|
||||
|
||||
PIdx const&
|
||||
reset_PlachementIndex(PIdx const& alternativeIndex)
|
||||
|
||||
void
|
||||
reset_PlacementIndex (PIdx const& alternativeIndex)
|
||||
{
|
||||
globalIndex = alternativeIndex;
|
||||
}
|
||||
|
||||
/** @internal restore the implicit PlacementIndex to its default implementation (=the session) */
|
||||
PIdx const&
|
||||
reset_PlachementIndex()
|
||||
void
|
||||
reset_PlacementIndex()
|
||||
{
|
||||
globalIndex.reset(0);
|
||||
globalIndex.reset();
|
||||
}
|
||||
|
||||
/** by default, this reaches for the PlacementIndex maintained within
|
||||
|
|
@ -129,11 +174,17 @@ namespace mobject {
|
|||
* PlacementIndex may have been \link #reset_PlacementIndex installed \endlink
|
||||
*/
|
||||
Placement<MObject> &
|
||||
fetch_PlachementIndex(Placement<MObject>::ID const& pID)
|
||||
fetch_PlacementIndex (Placement<MObject>::ID const& pID)
|
||||
{
|
||||
return getGlobalIndex()->find (pID);
|
||||
}
|
||||
|
||||
|
||||
/** @internal used by PlacementRef to implement a self-check */
|
||||
bool
|
||||
checkContains_PlacementIndex (Placement<MObject>::ID const& pID)
|
||||
{
|
||||
return getGlobalIndex()->contains (pID);
|
||||
}
|
||||
|
||||
|
||||
} // namespace mobject
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
//#include "pre.hpp"
|
||||
//#include "proc/mobject/session/locatingpin.hpp"
|
||||
//#include "proc/asset/pipe.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/factory.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
|
|
@ -47,11 +48,12 @@
|
|||
|
||||
|
||||
namespace mobject {
|
||||
|
||||
|
||||
using lumiera::factory::RefcountFac;
|
||||
using std::tr1::shared_ptr;
|
||||
using boost::scoped_ptr;
|
||||
using std::vector;
|
||||
|
||||
|
||||
class MObject;
|
||||
|
||||
|
||||
|
|
@ -67,7 +69,7 @@ namespace mobject {
|
|||
public:
|
||||
typedef Placement<MObject> PlacementMO;
|
||||
typedef PlacementRef<MObject> PRef;
|
||||
typedef PlacementMO::ID ID;
|
||||
typedef PlacementMO::ID const& ID;
|
||||
|
||||
|
||||
PlacementMO& find (ID) const;
|
||||
|
|
@ -75,21 +77,21 @@ namespace mobject {
|
|||
template<class MO>
|
||||
Placement<MO>& find (PlacementMO::Id<MO>) const;
|
||||
template<class MO>
|
||||
Placement<MO>& find (PlacementRef<MO>) const;
|
||||
Placement<MO>& find (PlacementRef<MO> const&) const;
|
||||
|
||||
PlacementMO& getScope (PlacementMO&) const;
|
||||
PlacementMO& getScope (ID) const;
|
||||
PlacementMO& getScope (PlacementMO const&) const;
|
||||
PlacementMO& getScope (ID) const;
|
||||
|
||||
vector<PRef> getReferrers (ID) const;
|
||||
vector<PRef> getReferrers (ID) const;
|
||||
|
||||
|
||||
/** retrieve the logical root scope */
|
||||
PlacementMO& getRoot() const;
|
||||
PlacementMO& getRoot() const;
|
||||
|
||||
/** diagnostic: number of indexed entries */
|
||||
size_t size() const;
|
||||
bool contains (PlacementMO const&) const;
|
||||
bool contains (ID const&) const;
|
||||
size_t size() const;
|
||||
bool contains (PlacementMO const&) const;
|
||||
bool contains (ID) const;
|
||||
|
||||
|
||||
/* == mutating operations == */
|
||||
|
|
@ -99,13 +101,16 @@ namespace mobject {
|
|||
bool remove (ID);
|
||||
|
||||
|
||||
typedef lumiera::factory::RefcountFac<PlacementIndex> Factory;
|
||||
typedef RefcountFac<PlacementIndex> Factory;
|
||||
|
||||
static Factory create;
|
||||
|
||||
~PlacementIndex();
|
||||
|
||||
protected:
|
||||
PlacementIndex() ;
|
||||
friend class Factory;
|
||||
|
||||
friend class lumiera::factory::Factory<PlacementIndex, lumiera::factory::Wrapper<PlacementIndex, shared_ptr<PlacementIndex> > >;
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API; probably have to split off an impl.class; but for now a PImpl is sufficient...
|
||||
|
||||
|
|
@ -114,16 +119,59 @@ namespace mobject {
|
|||
/** @internal there is an implicit PlacementIndex available on a global scale,
|
||||
* by default implemented within the current session. This function allows
|
||||
* to re-define this implicit index temporarily, e.g. for unit tests. */
|
||||
shared_ptr<PlacementIndex> const&
|
||||
reset_PlachementIndex(shared_ptr<PlacementIndex> const&) ;
|
||||
void
|
||||
reset_PlacementIndex(shared_ptr<PlacementIndex> const&) ;
|
||||
|
||||
/** @internal restore the implicit PlacementIndex to its default implementation (=the session) */
|
||||
shared_ptr<PlacementIndex> const&
|
||||
reset_PlachementIndex() ;
|
||||
void
|
||||
reset_PlacementIndex() ;
|
||||
|
||||
/** @internal access point for PlacementRef to the implicit global PlacementIndex */
|
||||
Placement<MObject> &
|
||||
fetch_PlachementIndex(Placement<MObject>::ID const&) ;
|
||||
fetch_PlacementIndex(Placement<MObject>::ID const&) ;
|
||||
|
||||
|
||||
|
||||
|
||||
/* === forwarding implementations of the templated API === */
|
||||
|
||||
template<class MO>
|
||||
inline Placement<MO>&
|
||||
PlacementIndex::find (PlacementMO::Id<MO> id) const
|
||||
{
|
||||
PlacementMO& result (find (id));
|
||||
REQUIRE (INSTANCEOF (MO, &result) );
|
||||
return static_cast<Placement<MO>&> (result);
|
||||
}
|
||||
|
||||
|
||||
template<class MO>
|
||||
inline Placement<MO>&
|
||||
PlacementIndex::find (PlacementRef<MO> const& pRef) const
|
||||
{
|
||||
PlacementMO::Id<MO> id (pRef);
|
||||
return find (id);
|
||||
}
|
||||
|
||||
|
||||
inline Placement<MObject>&
|
||||
PlacementIndex::getScope (PlacementMO const& p) const
|
||||
{
|
||||
return getScope(p.getID());
|
||||
}
|
||||
|
||||
inline bool
|
||||
PlacementIndex::contains (PlacementMO const& p) const
|
||||
{
|
||||
return contains (p.getID());
|
||||
}
|
||||
|
||||
inline bool
|
||||
PlacementIndex::remove (PlacementMO& p)
|
||||
{
|
||||
return remove (p.getID());
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace mobject
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@
|
|||
|
||||
|
||||
/** @file placement-ref.hpp
|
||||
**
|
||||
** @note there is a twist concerning the nominal Placement hierarchy
|
||||
** as generated by the return type of PlacementRef::operator*().
|
||||
** While the original Placement (as added to the session) might been
|
||||
** defined to mimic a more elaborate hierarchy (e.g. Placement<Track>
|
||||
** inherits from Placement<Meta>), the Placement returned here in
|
||||
** these cases will just be a subclass or Placement<MObject>
|
||||
** (which in the mentioned example would mean it couldn't be
|
||||
** passed to a API function expecting a Placement<Meta>).
|
||||
** This is uggly, but doesn't seem to bear any danger.
|
||||
**
|
||||
** @see Placement
|
||||
** @see PlacementRef_test
|
||||
|
|
@ -36,7 +46,9 @@
|
|||
//#include "pre.hpp"
|
||||
//#include "proc/mobject/session/locatingpin.hpp"
|
||||
//#include "proc/asset/pipe.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/explicitplacement.hpp" /////////////TODO this is ugly! Why can't placement::resolve() return a reference??
|
||||
|
||||
//#include <tr1/memory>
|
||||
|
||||
|
|
@ -50,8 +62,13 @@ namespace mobject {
|
|||
|
||||
// see placement-index.cpp
|
||||
Placement<MObject> &
|
||||
fetch_PlachementIndex(Placement<MObject>::ID const&) ;
|
||||
fetch_PlacementIndex(Placement<MObject>::ID const&) ;
|
||||
|
||||
bool
|
||||
checkContains_PlacementIndex (Placement<MObject>::ID const& pID) ;
|
||||
|
||||
|
||||
LUMIERA_ERROR_DECLARE (INVALID_PLACEMENTREF); ///< unresolvable placement reference, or of incompatible type
|
||||
|
||||
/**
|
||||
*/
|
||||
|
|
@ -59,7 +76,7 @@ namespace mobject {
|
|||
class PlacementRef
|
||||
{
|
||||
typedef Placement<MO> PlacementMO;
|
||||
typedef Placement<MObject>::ID _ID; ////TODO: superfluous...
|
||||
typedef Placement<MObject>::ID _ID; ////TODO: could we define const& here??
|
||||
typedef Placement<MObject>::Id<MO> _Id;
|
||||
|
||||
_Id id_;
|
||||
|
|
@ -96,7 +113,7 @@ namespace mobject {
|
|||
|
||||
template<class X>
|
||||
PlacementRef (PlacementRef<X> const& r) ///< extended copy ctor, when type X is assignable to MO
|
||||
: id_(r.id_)
|
||||
: id_(recast(r))
|
||||
{
|
||||
validate(id_);
|
||||
}
|
||||
|
|
@ -114,8 +131,8 @@ namespace mobject {
|
|||
PlacementRef&
|
||||
operator= (PlacementRef<X> const& r)
|
||||
{
|
||||
validate(r.id_);
|
||||
id_ = r.id_;
|
||||
validate(recast (r));
|
||||
id_ = recast(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -133,19 +150,65 @@ namespace mobject {
|
|||
|
||||
PlacementMO& operator*() const { return access(id_); } ///< dereferencing fetches referred Placement from Index
|
||||
|
||||
MO* operator->() const { return access(id_); } ///< provide access to pointee API by smart-ptr chaining
|
||||
PlacementMO& operator->() const { return access(id_); } ///< provide access to pointee API by smart-ptr chaining
|
||||
|
||||
operator string() const { return access(id_).operator string(); }
|
||||
size_t use_count() const { return access(id_).use_count(); }
|
||||
|
||||
|
||||
/* == accessing the embedded ID == */
|
||||
operator _Id const&() const { return id_; }
|
||||
LumieraUid getLUID() const { return id_.get(); }
|
||||
|
||||
template<class O>
|
||||
bool operator== (PlacementRef<O> const& o) const { return id_ == o; }
|
||||
template<class O>
|
||||
bool operator!= (PlacementRef<O> const& o) const { return id_ != o; }
|
||||
|
||||
|
||||
typedef _Id PlacementRef::*__unspecified_bool_type;
|
||||
|
||||
/** implicit conversion to "bool" */
|
||||
operator __unspecified_bool_type() const { return isValid()? &PlacementRef::id_ : 0; } // never throws
|
||||
bool operator! () const { return !isValid(); } // ditto
|
||||
|
||||
|
||||
|
||||
/* == forwarding part of the Placement-API == */
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
if (checkValidity())
|
||||
try
|
||||
{
|
||||
return access(id_).isValid();
|
||||
}
|
||||
catch (lumiera::error::Invalid&) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ExplicitPlacement resolve() const { return access(id_).resolve();}
|
||||
|
||||
|
||||
////////////////TODO more operations to come....
|
||||
|
||||
private:
|
||||
static void
|
||||
validate (_Id rId)
|
||||
bool
|
||||
checkValidity () const
|
||||
{
|
||||
if (!access(rId).isCompatible<MO>())
|
||||
throw error::Invalid(LUMIERA_ERROR_INVALID_PLACEMENTREF);
|
||||
return checkContains_PlacementIndex(this->id_);
|
||||
}
|
||||
|
||||
static void
|
||||
validate (_Id const& rId)
|
||||
{
|
||||
PlacementMO& pRef (access (rId));
|
||||
if (!(pRef.template isCompatible<MO>()))
|
||||
throw lumiera::error::Invalid("actual type of the resolved placement is incompatible",LUMIERA_ERROR_INVALID_PLACEMENTREF);
|
||||
|
||||
////////////////////////TODO: 1. better message, including type?
|
||||
////////////////////////TODO: 2. define a separate error-ID for the type mismatch!
|
||||
}
|
||||
|
||||
static _Id const&
|
||||
|
|
@ -162,10 +225,10 @@ namespace mobject {
|
|||
}
|
||||
|
||||
static PlacementMO&
|
||||
access (_Id placementID)
|
||||
access (_Id const& placementID)
|
||||
{
|
||||
Placement<MObject> & pla (fetch_PlachementIndex (placementID)); // may throw
|
||||
REQUIRE (pla);
|
||||
Placement<MObject> & pla (fetch_PlacementIndex (placementID)); // may throw
|
||||
REQUIRE (pla.isValid());
|
||||
ASSERT (pla.isCompatible<MO>());
|
||||
return static_cast<PlacementMO&> (pla);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ namespace mobject {
|
|||
public HashIndexed<Placement<MObject>, lib::hash::LuidH> //////TODO: really need to be inherited publicly?
|
||||
{
|
||||
protected:
|
||||
typedef HashIndexed<Placement<MObject>, lib::hash::LuidH> HashInd;
|
||||
typedef shared_ptr<MObject> _SmartPtr;
|
||||
typedef void (*Deleter)(MObject*);
|
||||
typedef lumiera::Time Time;
|
||||
|
|
@ -146,12 +147,14 @@ namespace mobject {
|
|||
bool
|
||||
isCompatible () const
|
||||
{
|
||||
return 0 != dynamic_cast<const Y*> (get());
|
||||
return 0 != dynamic_cast<Y*> (get());
|
||||
}
|
||||
|
||||
|
||||
operator string() const ;
|
||||
size_t use_count() const { return _SmartPtr::use_count(); }
|
||||
bool isValid() const { return _SmartPtr::use_count(); }
|
||||
|
||||
|
||||
virtual ~Placement() {};
|
||||
|
||||
|
|
@ -168,6 +171,7 @@ namespace mobject {
|
|||
* provide the resulting (explicit) placement.
|
||||
*/
|
||||
virtual ExplicitPlacement resolve () const;
|
||||
//////////////////////////TODO could resolve() return a reference? Otherwise placement-ref.hpp needs to include ExplicitPlacement
|
||||
|
||||
|
||||
protected:
|
||||
|
|
@ -194,6 +198,7 @@ namespace mobject {
|
|||
{
|
||||
protected:
|
||||
typedef Placement<B> _Parent;
|
||||
typedef typename _Parent::template Id<MO> const& _ID;
|
||||
typedef typename _Parent::Deleter Deleter;
|
||||
typedef typename _Parent::_SmartPtr _SmartPtr;
|
||||
|
||||
|
|
@ -211,6 +216,13 @@ namespace mobject {
|
|||
return static_cast<MO*>
|
||||
(_SmartPtr::operator-> ());
|
||||
}
|
||||
|
||||
_ID
|
||||
getID () const ///< @note overrides HashIndexed::getID to pass specific type information,
|
||||
{
|
||||
return _Parent::template recastID<MO>();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -219,6 +231,7 @@ namespace mobject {
|
|||
|
||||
|
||||
/** @todo cleanup uses of ref-to-placement. See Trac #115 */
|
||||
typedef Placement<MObject> PlacementMO;
|
||||
typedef Placement<MObject> PMO;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,182 +21,181 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
#include "proc/mobject/mobject.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 mobject {
|
||||
namespace session {
|
||||
|
||||
inline LocatingPin*
|
||||
cloneChain (const scoped_ptr<LocatingPin>& chain)
|
||||
{
|
||||
namespace session
|
||||
{
|
||||
inline LocatingPin*
|
||||
cloneChain (const scoped_ptr<LocatingPin>& chain)
|
||||
{
|
||||
if (!chain)
|
||||
return 0;
|
||||
else
|
||||
return chain->clone();
|
||||
}
|
||||
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_(cloneChain (other.next_))
|
||||
{ }
|
||||
|
||||
|
||||
LocatingPin&
|
||||
LocatingPin::operator= (const LocatingPin& other)
|
||||
{
|
||||
if (this != &other)
|
||||
this->next_.reset (cloneChain (other.next_));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocatingPin*
|
||||
LocatingPin::clone () const
|
||||
{
|
||||
return new LocatingPin(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LocatingPin&
|
||||
LocatingPin::addChain (LocatingPin* newLp) ///< @note we take ownership of newLp
|
||||
{
|
||||
REQUIRE (newLp);
|
||||
REQUIRE (!newLp->next_, "can insert only single LocatingPins");
|
||||
|
||||
|
||||
/** it's OK to copy a LocainngPin,
|
||||
* causing duplication of any chained lPins
|
||||
*/
|
||||
LocatingPin::LocatingPin (const LocatingPin& other)
|
||||
: next_(cloneChain (other.next_))
|
||||
{ }
|
||||
|
||||
|
||||
LocatingPin&
|
||||
LocatingPin::operator= (const LocatingPin& other)
|
||||
{
|
||||
if (this != &other)
|
||||
this->next_.reset (cloneChain (other.next_));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LocatingPin*
|
||||
LocatingPin::clone () const
|
||||
{
|
||||
return new LocatingPin(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LocatingPin&
|
||||
LocatingPin::addChain (LocatingPin* newLp) ///< @note we take ownership of newLp
|
||||
{
|
||||
REQUIRE (newLp);
|
||||
REQUIRE (!newLp->next_, "can insert only single LocatingPins");
|
||||
|
||||
if (next_ && newLp->getPrioLevel() > next_->getPrioLevel())
|
||||
return next_->addChain (newLp);
|
||||
else
|
||||
{
|
||||
scoped_ptr<LocatingPin> tmp_next (newLp);
|
||||
tmp_next->next_.swap(next_);
|
||||
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
|
||||
* @todo we are packing and unpacking the information (time,track)
|
||||
* several times. Ichthyo considers a more elegant solution.
|
||||
*/
|
||||
const LocatingPin::SolutionData
|
||||
LocatingPin::resolve () const
|
||||
{
|
||||
LocatingSolution solution;
|
||||
resolve (solution);
|
||||
return SolutionData (solution.getTime(), solution.getPipe());
|
||||
}
|
||||
|
||||
bool
|
||||
LocatingPin::isOverdetermined () const
|
||||
{
|
||||
LocatingSolution solution;
|
||||
resolve (solution);
|
||||
return solution.is_impossible();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
LocatingPin::resolve (LocatingSolution& solution) const
|
||||
{
|
||||
if (!solution.still_to_solve())
|
||||
return;
|
||||
this->intersect (solution);
|
||||
if (next_ && solution.still_to_solve())
|
||||
next_->resolve(solution);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocatingPin::intersect (LocatingSolution& solution) const
|
||||
{
|
||||
REQUIRE (solution.still_to_solve());
|
||||
// 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::Pipe
|
||||
LocatingPin::LocatingSolution::getPipe()
|
||||
{
|
||||
UNIMPLEMENTED ("get effective Pipe of Solution");
|
||||
return Pipe ();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
LocatingPin::LocatingSolution::still_to_solve ()
|
||||
{
|
||||
return !(is_definite() || is_impossible());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* === Factory functions for adding LocatingPins === */
|
||||
|
||||
FixedLocation&
|
||||
LocatingPin::operator() (Time start, Track track)
|
||||
{
|
||||
return static_cast<FixedLocation&>
|
||||
(addChain (new FixedLocation (start, track)));
|
||||
}
|
||||
|
||||
|
||||
RelativeLocation&
|
||||
LocatingPin::operator() (PlacementRef& refObj, Time offset)
|
||||
{
|
||||
return static_cast<RelativeLocation&>
|
||||
(addChain (new RelativeLocation (refObj, offset)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace mobject::session
|
||||
|
||||
} // namespace mobject
|
||||
if (next_ && newLp->getPrioLevel() > next_->getPrioLevel())
|
||||
return next_->addChain (newLp);
|
||||
else
|
||||
{
|
||||
scoped_ptr<LocatingPin> tmp_next (newLp);
|
||||
tmp_next->next_.swap(next_);
|
||||
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
|
||||
* @todo we are packing and unpacking the information (time,track)
|
||||
* several times. Ichthyo considers a more elegant solution.
|
||||
*/
|
||||
const LocatingPin::SolutionData
|
||||
LocatingPin::resolve () const
|
||||
{
|
||||
LocatingSolution solution;
|
||||
resolve (solution);
|
||||
return SolutionData (solution.getTime(), solution.getPipe());
|
||||
}
|
||||
|
||||
bool
|
||||
LocatingPin::isOverdetermined () const
|
||||
{
|
||||
LocatingSolution solution;
|
||||
resolve (solution);
|
||||
return solution.is_impossible();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
LocatingPin::resolve (LocatingSolution& solution) const
|
||||
{
|
||||
if (!solution.still_to_solve())
|
||||
return;
|
||||
this->intersect (solution);
|
||||
if (next_ && solution.still_to_solve())
|
||||
next_->resolve(solution);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocatingPin::intersect (LocatingSolution& solution) const
|
||||
{
|
||||
REQUIRE (solution.still_to_solve());
|
||||
// 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::Pipe
|
||||
LocatingPin::LocatingSolution::getPipe()
|
||||
{
|
||||
UNIMPLEMENTED ("get effective Pipe of Solution");
|
||||
return Pipe ();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
LocatingPin::LocatingSolution::still_to_solve ()
|
||||
{
|
||||
return !(is_definite() || is_impossible());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* === Factory functions for adding LocatingPins === */
|
||||
|
||||
FixedLocation&
|
||||
LocatingPin::operator() (Time start, Track track)
|
||||
{
|
||||
return static_cast<FixedLocation&>
|
||||
(addChain (new FixedLocation (start, track)));
|
||||
}
|
||||
|
||||
|
||||
RelativeLocation&
|
||||
LocatingPin::operator() (PlaRef& refObj, Time offset)
|
||||
{
|
||||
return static_cast<RelativeLocation&>
|
||||
(addChain (new RelativeLocation (refObj, offset)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace mobject::session
|
||||
|
|
|
|||
|
|
@ -61,17 +61,19 @@ namespace asset { class Pipe; }
|
|||
namespace mobject {
|
||||
|
||||
class MObject;
|
||||
|
||||
|
||||
///////////////////////////////////////////TODO: all those dependencies are just a plain mess right now.
|
||||
//
|
||||
//template<class MO, class B=MObject>
|
||||
//class Placement ;
|
||||
//typedef Placement<MObject> PMO;
|
||||
|
||||
template<class MO =MObject>
|
||||
|
||||
template<class MO>
|
||||
class PlacementRef; ///TODO: as of 5/09 the idea is to phase out direct dependency on the placement class and recast those dependencies in terms of PlacementRef
|
||||
|
||||
|
||||
|
||||
typedef PlacementRef<MObject> PlaRef;
|
||||
|
||||
|
||||
namespace session {
|
||||
|
||||
class FixedLocation;
|
||||
|
|
@ -117,7 +119,7 @@ namespace mobject {
|
|||
/* Factory functions for adding LocatingPins */
|
||||
|
||||
FixedLocation& operator() (Time start, Track track=0);
|
||||
RelativeLocation& operator() (PlacementRef<>& refObj, Time offset=Time(0)); //////////TODO: warning, just a dummy placeholder for now!!
|
||||
RelativeLocation& operator() (PlacementRef<MObject>& refObj, Time offset=Time(0)); //////////TODO: warning, just a dummy placeholder for now!!
|
||||
|
||||
LocatingPin (const LocatingPin&);
|
||||
LocatingPin& operator= (const LocatingPin&);
|
||||
|
|
|
|||
|
|
@ -30,56 +30,52 @@
|
|||
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
|
||||
|
||||
/**
|
||||
* @todo just a design sketch, nothing finished yet.
|
||||
* possibly to be reworked or phased out completely.
|
||||
* See Trac #100
|
||||
*/
|
||||
class RelativeLocation : public LocatingPin
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @todo just a design sketch, nothing finished yet.
|
||||
* possibly to be reworked or phased out completely.
|
||||
* See Trac #100
|
||||
*/
|
||||
class RelativeLocation : public LocatingPin
|
||||
{
|
||||
// const PMO & anchor_; ////////////TODO: ooooops, this is a nasty design problem!!!
|
||||
|
||||
const PlacementRef anchor_;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* the possible kinds of RelativePlacements
|
||||
*/
|
||||
enum RelType
|
||||
{ SAMETIME /**< place subject at the same time as the anchor */
|
||||
, ATTACH /**< attach subject to anchor (e.g. an effect to a clip) */
|
||||
};
|
||||
|
||||
protected:
|
||||
RelativeLocation (PlacementRef const& a, Time ofs) : anchor_(a), offset_(ofs) { }
|
||||
friend class LocatingPin;
|
||||
|
||||
/** the kind of relation denoted by this Placement */
|
||||
RelType relType;
|
||||
|
||||
/** Offset the actual position by this (time) value relative to the anchor point. */
|
||||
Time offset_;
|
||||
//TODO: suitable representation?
|
||||
|
||||
|
||||
virtual void intersect (LocatingSolution&) const;
|
||||
|
||||
|
||||
public:
|
||||
virtual RelativeLocation* clone () const;
|
||||
|
||||
|
||||
const PlaRef anchor_;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* the possible kinds of RelativePlacements
|
||||
*/
|
||||
enum RelType
|
||||
{ SAMETIME /**< place subject at the same time as the anchor */
|
||||
, ATTACH /**< attach subject to anchor (e.g. an effect to a clip) */
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace mobject::session
|
||||
|
||||
} // namespace mobject
|
||||
|
||||
protected:
|
||||
RelativeLocation (PlaRef const& a, Time ofs) : anchor_(a), offset_(ofs) { }
|
||||
friend class LocatingPin;
|
||||
|
||||
/** the kind of relation denoted by this Placement */
|
||||
RelType relType;
|
||||
|
||||
/** Offset the actual position by this (time) value relative to the anchor point. */
|
||||
Time offset_;
|
||||
//TODO: suitable representation?
|
||||
|
||||
|
||||
virtual void intersect (LocatingSolution&) const;
|
||||
|
||||
|
||||
public:
|
||||
virtual RelativeLocation* clone () const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace mobject::session
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -145,8 +145,8 @@ namespace session {
|
|||
}
|
||||
|
||||
|
||||
shared_ptr<PlacementIndex>
|
||||
getCurrentIndex ()
|
||||
shared_ptr<PlacementIndex>&
|
||||
SessManagerImpl::getCurrentIndex ()
|
||||
{
|
||||
return static_cast<SessManagerImpl&> (Session::current).pImpl_->pIdx_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace session {
|
|||
/* ==== proc layer internal API ==== */
|
||||
|
||||
/** @internal access point for PlacementIndex and PlacementRef */
|
||||
static shared_ptr<PlacementIndex> getCurrentIndex () ;
|
||||
static shared_ptr<PlacementIndex>& getCurrentIndex () ;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ namespace session {
|
|||
|
||||
/** Placement<Track> defined to be subclass of Placement<Meta> */
|
||||
template class Placement<session::Track, session::Meta>;
|
||||
typedef Placement<session::Track, session::Meta> PTrack;
|
||||
|
||||
} // namespace mobject
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -51,6 +51,16 @@ namespace test {
|
|||
namespace command1 {
|
||||
|
||||
////////////////////////////////////////////TODO braindump
|
||||
/*
|
||||
bind: opFunc(a,b,c) -> op(void)
|
||||
|
||||
curry(opFunc) (a) (b) (c)
|
||||
|
||||
pAppl(func, x) -> func2 (b, c)
|
||||
|
||||
return bind( recursion(), param)
|
||||
|
||||
*/
|
||||
////////////////////////////////////////////TODO braindump
|
||||
|
||||
}
|
||||
|
|
@ -72,7 +82,6 @@ namespace test {
|
|||
*/
|
||||
class CommandBasic_test : public Test
|
||||
{
|
||||
typedef shared_ptr<PlacementIndex> PIdx;
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "proc/mobject/mobject-ref.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
#include "proc/mobject/placement-index.hpp"
|
||||
#include "proc/mobject/session/clip.hpp"
|
||||
#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
|
|
@ -83,6 +84,7 @@ namespace test {
|
|||
ASSERT (2 == pClip2.use_count());
|
||||
|
||||
|
||||
#if 0 /////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
// Prepare an (test)Index
|
||||
typedef shared_ptr<PlacementIndex> PIdx;
|
||||
PIdx index (PlacementIndex::create());
|
||||
|
|
@ -125,6 +127,7 @@ namespace test {
|
|||
ASSERT (0 == index->size());
|
||||
ASSERT (2 == pClip1.use_count());
|
||||
ASSERT (2 == pClip2.use_count());
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
reset_PlacementIndex();
|
||||
}
|
||||
|
||||
|
|
@ -133,6 +136,7 @@ namespace test {
|
|||
void
|
||||
checkBuildMObjectRef (REF refObj, void* placementAdr)
|
||||
{
|
||||
#if 0 /////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
MORef<Clip> rMO;
|
||||
ASSERT (!rMO); // still empty (not bound)
|
||||
cout << rMO << endl;
|
||||
|
|
@ -167,11 +171,13 @@ namespace test {
|
|||
ASSERT (exPla.time == start); // recovered Placement resolves to the same time as provided by the proxied API
|
||||
ASSERT (4 == refP.use_count()); // but now we've indeed created an additional owner (exPla)
|
||||
ASSERT (4 == rMO.use_count());
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
}
|
||||
|
||||
void
|
||||
checkLifecylce (PMObj const& p1, PMObj const& p1)
|
||||
checkLifecylce (PMObj const& p1, PMObj const& p2)
|
||||
{
|
||||
#if 0 /////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
ASSERT (2 == p1.use_count());
|
||||
ASSERT (2 == p2.use_count());
|
||||
|
||||
|
|
@ -203,11 +209,13 @@ namespace test {
|
|||
|
||||
VERIFY_ERROR (INVALID_PLACEMENTREF, rMO.getPlacement() );
|
||||
VERIFY_ERROR (INVALID_MOBJECTREF, rMO->getMedia() );
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
}
|
||||
|
||||
void
|
||||
checkTypeHandling (LumieraUid luid)
|
||||
{
|
||||
#if 0 /////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
MObjectRef rMObj;
|
||||
MORef<Clip> rClip;
|
||||
MORef<TestSubMO1> rSub1;
|
||||
|
|
@ -248,6 +256,7 @@ namespace test {
|
|||
|
||||
cout << rClip << endl;
|
||||
cout << rClip->getMedia()->ident << endl;
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "proc/mobject/session/clip.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <tr1/memory>
|
||||
|
|
@ -47,7 +48,7 @@ namespace test {
|
|||
using session::Clip;
|
||||
using lib::test::showSizeof;
|
||||
using namespace mobject::test;
|
||||
using error::LUMIERA_ERROR_ASSERTION;
|
||||
using lumiera::error::LUMIERA_ERROR_ASSERTION;
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "lib/lumitime.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
#include "proc/mobject/placement-index.hpp"
|
||||
#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
|
||||
|
|
@ -33,6 +34,7 @@
|
|||
using lumiera::Time;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
namespace mobject {
|
||||
|
|
@ -40,7 +42,17 @@ namespace session {
|
|||
namespace test {
|
||||
|
||||
using namespace mobject::test;
|
||||
|
||||
typedef TestPlacement<TestSubMO21> PSub;
|
||||
|
||||
|
||||
template<class A, class B>
|
||||
inline bool
|
||||
isSameObject (A const& a, B const& b)
|
||||
{
|
||||
return static_cast<const void*> (&a)
|
||||
== static_cast<const void*> (&b);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* @test properties and behaviour of the reference-mechanism for Placements.
|
||||
|
|
@ -57,8 +69,6 @@ namespace test {
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
typedef TestPlacement<TestSubMO21> PSub;
|
||||
|
||||
PSub p1(*new TestSubMO21);
|
||||
PSub p2(*new TestSubMO21);
|
||||
p2.chain(Time(2)); // define start time of Placement-2 to be at t=2
|
||||
|
|
@ -73,7 +83,7 @@ namespace test {
|
|||
index->insert (p2, root);
|
||||
ASSERT (2 == index->size());
|
||||
|
||||
Placement::Id<TestSubMO21> id2 = p2.getID();
|
||||
PlacementMO::Id<TestSubMO21> id2 = p2.recastID<TestSubMO21>();
|
||||
ASSERT (id2);
|
||||
ASSERT (id2 != p1.getID());
|
||||
|
||||
|
|
@ -90,9 +100,9 @@ namespace test {
|
|||
ASSERT (ref2 == refX);
|
||||
|
||||
// indeed a "reference": resolves to the same memory location
|
||||
ASSERT (&p1 == &*ref1);
|
||||
ASSERT (&p2 == &*ref2);
|
||||
ASSERT (&p2 == &*refX);
|
||||
ASSERT (isSameObject (p1, *ref1));
|
||||
ASSERT (isSameObject (p2, *ref2));
|
||||
ASSERT (isSameObject (p2, *refX));
|
||||
|
||||
cout << string(*ref1) << endl;
|
||||
cout << string(*ref2) << endl;
|
||||
|
|
@ -106,7 +116,7 @@ namespace test {
|
|||
ASSERT (exPla.time == 2); // indeed get back the time we set on p2 above
|
||||
ASSERT (2 == ref2.use_count()); // exPla shares ownership with p2
|
||||
|
||||
ASSERT (indey->contains(ref1)); // ref can stand-in for a placement-ID
|
||||
ASSERT (index->contains(ref1)); // ref can stand-in for a placement-ID
|
||||
ASSERT (sizeof(id2) == sizeof(ref2)); // (and is actually implemented based on an ID)
|
||||
|
||||
// assignment on placement refs
|
||||
|
|
@ -118,24 +128,24 @@ namespace test {
|
|||
// re-assignment with a new placement
|
||||
refX = p2;
|
||||
ASSERT (refX == ref2);
|
||||
ASSERT (&*refX == &p2);
|
||||
ASSERT (isSameObject (*refX, p2));
|
||||
refX = p1.getID();
|
||||
ASSERT (refX == ref1);
|
||||
ASSERT (refX != ref2);
|
||||
ASSERT (&*refX == &p1);
|
||||
ASSERT (isSameObject (*refX, p1));
|
||||
|
||||
LumieraUid luid2 (p2.getID().get());
|
||||
refX = luid2; // assignment works even based on a plain LUID
|
||||
ref2 = ref1;
|
||||
ref1 = refX; // dynamic type check when downcasting
|
||||
ASSERT (&p1 == &*ref2);
|
||||
ASSERT (&p2 == &*ref1);
|
||||
ASSERT (isSameObject (p1, *ref2));
|
||||
ASSERT (isSameObject (p2, *ref1));
|
||||
refX = ref2;
|
||||
ref2 = ref1;
|
||||
ref1 = refX;
|
||||
ASSERT (&p1 == &*ref1);
|
||||
ASSERT (&p1 == &*refX);
|
||||
ASSERT (&p2 == &*ref2);
|
||||
ASSERT (isSameObject (p1, *ref1));
|
||||
ASSERT (isSameObject (p1, *refX));
|
||||
ASSERT (isSameObject (p2, *ref2));
|
||||
ASSERT (ref1 != ref2);
|
||||
ASSERT (ref1 == refX);
|
||||
ASSERT (ref2 != refX);
|
||||
|
|
|
|||
|
|
@ -43,56 +43,51 @@ using proc_interface::IDA;
|
|||
using std::tr1::dynamic_pointer_cast; /// TODO only temp
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* @test removing a test clip from the EDL.
|
||||
* @see mobject::session::Clip
|
||||
* @see mobject::session::EDL
|
||||
*/
|
||||
class DeleteClip_test : public Test
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* @test removing a test clip from the EDL.
|
||||
* @see mobject::session::Clip
|
||||
* @see mobject::session::EDL
|
||||
*/
|
||||
class DeleteClip_test : public Test
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
buildTestseesion1();
|
||||
PSess sess = Session::current;
|
||||
AssetManager& aMang = AssetManager::instance();
|
||||
|
||||
UNIMPLEMENTED("typesafe searching for MObjects in the EDL");
|
||||
buildTestsession1();
|
||||
PSess sess = Session::current;
|
||||
AssetManager& aMang = AssetManager::instance();
|
||||
|
||||
UNIMPLEMENTED("typesafe searching for MObjects in the EDL");
|
||||
|
||||
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////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
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TODO: work out how to search within 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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (DeleteClip_test, "function session");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace session
|
||||
|
||||
} // namespace mobject
|
||||
/** Register this test class... */
|
||||
LAUNCHER (DeleteClip_test, "function session");
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
|
|||
|
|
@ -39,62 +39,55 @@ using std::string;
|
|||
using std::cout;
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* @test (re)building the ExplicitPlacement objects from the objects
|
||||
* placed into the Session/EDL.
|
||||
* @see mobject::session::Fixture
|
||||
* @see mobject::ExplicitPlacement
|
||||
*/
|
||||
class RebuildFixture_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg arg)
|
||||
{
|
||||
PSess sess = Session::current;
|
||||
sess.clear();
|
||||
buildTestseesion1();
|
||||
ASSERT (sess->isValid());
|
||||
sess->rebuildFixture();
|
||||
TODO ("check the fixture has been touched. e.g. by hash.");
|
||||
TODO ("query all Placements of all Clips (via AssetManager). Verify explicit plac contained in Fixture.");
|
||||
|
||||
UNIMPLEMENTED ("iterate over fixture");
|
||||
// TODO
|
||||
// for_each (sess->getFixture(),
|
||||
// bind (&check_is_from_EDL, _1, sess.getEDL()));
|
||||
|
||||
TODO ("can we check the other direction, from EDL to Fixture??");
|
||||
}
|
||||
|
||||
static void
|
||||
check_is_from_EDL (PMO explicitPlacement, EDL& edl)
|
||||
{
|
||||
|
||||
////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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (RebuildFixture_test, "unit session");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
} // namespace session
|
||||
|
||||
} // namespace mobject
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* @test (re)building the ExplicitPlacement objects from the objects
|
||||
* placed into the Session/EDL.
|
||||
* @see mobject::session::Fixture
|
||||
* @see mobject::ExplicitPlacement
|
||||
*/
|
||||
class RebuildFixture_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg arg)
|
||||
{
|
||||
PSess sess = Session::current;
|
||||
sess.clear();
|
||||
buildTestsession1();
|
||||
ASSERT (sess->isValid());
|
||||
sess->rebuildFixture();
|
||||
TODO ("check the fixture has been touched. e.g. by hash.");
|
||||
TODO ("query all Placements of all Clips (via AssetManager). Verify explicit plac contained in Fixture.");
|
||||
|
||||
UNIMPLEMENTED ("iterate over fixture");
|
||||
// TODO
|
||||
// for_each (sess->getFixture(),
|
||||
// bind (&check_is_from_EDL, _1, sess.getEDL()));
|
||||
|
||||
TODO ("can we check the other direction, from EDL to Fixture??");
|
||||
}
|
||||
|
||||
static void
|
||||
check_is_from_EDL (PMO explicitPlacement, EDL& edl)
|
||||
{
|
||||
|
||||
////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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (RebuildFixture_test, "unit session");
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
|
|||
|
|
@ -33,111 +33,109 @@ using std::string;
|
|||
using std::cout;
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Check the session management operations provided by mobject::session::Seesion
|
||||
* This includes accessing the current Session (somewhat a singleton).
|
||||
* @todo load a Mock session
|
||||
* @todo create a session and save (serialize) it
|
||||
* @todo load a real test session
|
||||
*/
|
||||
class SessionManager_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg arg)
|
||||
{
|
||||
getCurrentSession ();
|
||||
clearSession();
|
||||
loadMockSession();
|
||||
|
||||
clearSession();
|
||||
buildTestseesion1();
|
||||
string serialized;
|
||||
saveSession (serialized);
|
||||
loadSession (serialized);
|
||||
ASSERT (checkTestsession1());
|
||||
}
|
||||
|
||||
/** @test accessing the current (global) session
|
||||
*/
|
||||
void
|
||||
getCurrentSession ()
|
||||
{
|
||||
PSess sess = Session::current;
|
||||
ASSERT (sess->isValid());
|
||||
}
|
||||
|
||||
/** @test clear current session contents
|
||||
* without resetting global session config.
|
||||
* @todo implement all session content, implement
|
||||
* mobject and asset deletion operations.
|
||||
*/
|
||||
void
|
||||
clearSession ()
|
||||
{
|
||||
UNIMPLEMENTED ("clear objects in current session");
|
||||
Session::current.clear();
|
||||
}
|
||||
|
||||
/** @test reset global session config and start with
|
||||
* a pristine default session.
|
||||
* @todo define the "global session config", implement session default ctor
|
||||
*/
|
||||
void
|
||||
resetSession ()
|
||||
{
|
||||
UNIMPLEMENTED ("construct a pristine session");
|
||||
Session::current.reset();
|
||||
}
|
||||
|
||||
/** @test use a mock session serializer to load
|
||||
* a preconfigured test session. Verify
|
||||
* objects are wired correctly.
|
||||
* @todo implement rebuilding session, implement mock session serializer
|
||||
*/
|
||||
void
|
||||
loadMockSession ()
|
||||
{
|
||||
UNIMPLEMENTED ("rebuild session using a mock serializer");
|
||||
}
|
||||
|
||||
/** @test load serialized session using the
|
||||
* real session serializer implementation.
|
||||
* @param src string with serialized session data
|
||||
* @todo implement real session serializer
|
||||
*/
|
||||
void
|
||||
loadSession (const string& src)
|
||||
{
|
||||
UNIMPLEMENTED ("loding real sesion");
|
||||
}
|
||||
|
||||
/** @test serialize (save) the current session
|
||||
* @param dest string recieving the generated serialized stream
|
||||
* @todo implement real session serializer
|
||||
*/
|
||||
void
|
||||
saveSession (string& dest)
|
||||
{
|
||||
UNIMPLEMENTED ("serialize current session");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (SessionManager_test, "function session");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
} // namespace session
|
||||
|
||||
} // namespace mobject
|
||||
|
||||
/*******************************************************************************
|
||||
* Check the session management operations provided by mobject::session::Session
|
||||
* This includes accessing the current Session (somewhat a singleton).
|
||||
* @todo load a Mock session
|
||||
* @todo create a session and save (serialise) it
|
||||
* @todo load a real test session
|
||||
*/
|
||||
class SessionManager_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg arg)
|
||||
{
|
||||
getCurrentSession ();
|
||||
clearSession();
|
||||
loadMockSession();
|
||||
|
||||
clearSession();
|
||||
buildTestsession1();
|
||||
string serialized;
|
||||
saveSession (serialized);
|
||||
loadSession (serialized);
|
||||
ASSERT (checkTestsession1());
|
||||
}
|
||||
|
||||
|
||||
/** @test accessing the current (global) session */
|
||||
void
|
||||
getCurrentSession ()
|
||||
{
|
||||
PSess sess = Session::current;
|
||||
ASSERT (sess->isValid());
|
||||
}
|
||||
|
||||
|
||||
/** @test clear current session contents
|
||||
* without resetting global session config.
|
||||
* @todo implement all session content, implement
|
||||
* mobject and asset deletion operations.
|
||||
*/
|
||||
void
|
||||
clearSession ()
|
||||
{
|
||||
UNIMPLEMENTED ("clear objects in current session");
|
||||
Session::current.clear();
|
||||
}
|
||||
|
||||
|
||||
/** @test reset global session config and start with
|
||||
* a pristine default session.
|
||||
* @todo define the "global session config", implement session default ctor
|
||||
*/
|
||||
void
|
||||
resetSession ()
|
||||
{
|
||||
UNIMPLEMENTED ("construct a pristine session");
|
||||
Session::current.reset();
|
||||
}
|
||||
|
||||
|
||||
/** @test use a mock session serialiser to load
|
||||
* a preconfigured test session. Verify
|
||||
* objects are wired correctly.
|
||||
* @todo implement rebuilding session, implement mock session serialiser
|
||||
*/
|
||||
void
|
||||
loadMockSession ()
|
||||
{
|
||||
UNIMPLEMENTED ("rebuild session using a mock serialiser");
|
||||
}
|
||||
|
||||
|
||||
/** @test load serialised session using the
|
||||
* real session serialiser implementation.
|
||||
* @param src string with serialised session data
|
||||
* @todo implement real session serialiser
|
||||
*/
|
||||
void
|
||||
loadSession (const string& src)
|
||||
{
|
||||
UNIMPLEMENTED ("loading real session");
|
||||
}
|
||||
|
||||
|
||||
/** @test serialise (save) the current session
|
||||
* @param dest string receiving the generated serialised stream
|
||||
* @todo implement real session serialiser
|
||||
*/
|
||||
void
|
||||
saveSession (string& dest)
|
||||
{
|
||||
UNIMPLEMENTED ("Serialise current session");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (SessionManager_test, "function session");
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
|
|||
|
|
@ -28,65 +28,59 @@
|
|||
#include "proc/asset/clip.hpp"
|
||||
#include "lib/singleton.hpp"
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
typedef shared_ptr<asset::Media> PM;
|
||||
typedef backend_interface::MediaAccessFacade MAF;
|
||||
using backend_interface::test::MediaAccessMock;
|
||||
using asset::VIDEO;
|
||||
|
||||
|
||||
|
||||
asset::Media &
|
||||
createTestMedia ()
|
||||
{
|
||||
// install Mock-Interface to Lumiera backend
|
||||
MAF::instance.injectSubclass (new MediaAccessMock);
|
||||
PM media = asset::Media::create("test-2", VIDEO); // query magic filename
|
||||
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_))
|
||||
{ }
|
||||
};
|
||||
|
||||
lumiera::Singleton<Testbed> testbed_1; // invoke ctor when creating first TestClip...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TestClip::TestClip ()
|
||||
: Clip(testbed_1().clipA_,
|
||||
testbed_1().media_)
|
||||
{
|
||||
ASSERT (isValid());
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
} // namespace session
|
||||
|
||||
} // namespace mobject
|
||||
typedef shared_ptr<asset::Media> PM;
|
||||
typedef backend_interface::MediaAccessFacade MAF;
|
||||
using backend_interface::test::MediaAccessMock;
|
||||
using asset::VIDEO;
|
||||
|
||||
|
||||
|
||||
asset::Media &
|
||||
createTestMedia ()
|
||||
{
|
||||
// install Mock-Interface to Lumiera backend
|
||||
MAF::instance.injectSubclass (new MediaAccessMock);
|
||||
PM media = asset::Media::create("test-2", VIDEO); // query magic filename
|
||||
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_))
|
||||
{ }
|
||||
};
|
||||
|
||||
lumiera::Singleton<Testbed> testbed_1; // invoke ctor when creating first TestClip...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TestClip::TestClip ()
|
||||
: Clip(testbed_1().clipA_,
|
||||
testbed_1().media_)
|
||||
{
|
||||
ASSERT (isValid());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
|
|||
|
|
@ -36,54 +36,49 @@ using std::tr1::shared_ptr;
|
|||
using std::string;
|
||||
|
||||
|
||||
namespace mobject
|
||||
{
|
||||
namespace session
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
class TestPlacement;
|
||||
|
||||
/**
|
||||
* Sample or Test Clip for checking
|
||||
* various EDL, session and builder operations.
|
||||
* @todo make this usable as Mock object to record invoked operations.
|
||||
*
|
||||
*/
|
||||
class TestClip : public mobject::session::Clip
|
||||
{
|
||||
|
||||
TestClip ();
|
||||
static void deleter (MObject* mo) { delete (TestClip*)mo; }
|
||||
|
||||
friend class TestPlacement;
|
||||
|
||||
public:
|
||||
static Placement<Clip> create () ;
|
||||
};
|
||||
|
||||
|
||||
class TestPlacement : public Placement<Clip>
|
||||
{
|
||||
|
||||
public:
|
||||
TestPlacement (TestClip & subject)
|
||||
: Placement<Clip> (subject, &TestClip::deleter)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
inline Placement<Clip>
|
||||
TestClip::create()
|
||||
{
|
||||
return TestPlacement (*new TestClip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
} // namespace session
|
||||
|
||||
} // namespace mobject
|
||||
|
||||
class TestPlacement;
|
||||
|
||||
/**
|
||||
* Sample or Test Clip for checking
|
||||
* various EDL, session and builder operations.
|
||||
* @todo make this usable as Mock object to record invoked operations.
|
||||
*
|
||||
*/
|
||||
class TestClip : public mobject::session::Clip
|
||||
{
|
||||
|
||||
TestClip ();
|
||||
static void deleter (MObject* mo) { delete (TestClip*)mo; }
|
||||
|
||||
friend class TestPlacement;
|
||||
|
||||
public:
|
||||
static Placement<Clip> create () ;
|
||||
};
|
||||
|
||||
|
||||
class TestPlacement : public Placement<Clip>
|
||||
{
|
||||
|
||||
public:
|
||||
TestPlacement (TestClip & subject)
|
||||
: Placement<Clip> (subject, &TestClip::deleter)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
inline Placement<Clip>
|
||||
TestClip::create()
|
||||
{
|
||||
return TestPlacement (*new TestClip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue