fixing, stubbing, and some chainsaw surgery to get half-finished code through the compiler

This commit is contained in:
Fischlurch 2009-06-09 09:05:19 +02:00
parent 3a7de1654a
commit 102e96891b
24 changed files with 817 additions and 626 deletions

View file

@ -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)
{

View file

@ -43,7 +43,7 @@
namespace control {
using lumiera::Symbol;
// using lumiera::Symbol;
// using std::tr1::shared_ptr;

View file

@ -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),

View file

@ -46,6 +46,9 @@ namespace mobject {
/** */
LUMIERA_ERROR_DEFINE (INVALID_PLACEMENTREF, "unresolvable placement reference, or of incompatible type");

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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&);

View file

@ -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

View file

@ -145,8 +145,8 @@ namespace session {
}
shared_ptr<PlacementIndex>
getCurrentIndex ()
shared_ptr<PlacementIndex>&
SessManagerImpl::getCurrentIndex ()
{
return static_cast<SessManagerImpl&> (Session::current).pImpl_->pIdx_;
}

View file

@ -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 () ;
};

View file

@ -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

View file

@ -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)

View file

@ -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.....!!!!!
}
};

View file

@ -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;
/***************************************************************************************

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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