MobjectRef_test passes compiler as a whole
This commit is contained in:
parent
71428ccf6f
commit
26972376de
3 changed files with 89 additions and 31 deletions
|
|
@ -48,6 +48,7 @@ namespace mobject {
|
|||
|
||||
LUMIERA_ERROR_DEFINE (INVALID_PLACEMENTREF, "unresolvable placement reference, or of incompatible type");
|
||||
LUMIERA_ERROR_DEFINE (BOTTOM_PLACEMENTREF, "NIL placement-ID marker encountered.");
|
||||
LUMIERA_ERROR_DEFINE (BOTTOM_MOBJECTREF, "NIL MObjectRef encountered");
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,30 @@
|
|||
|
||||
|
||||
/** @file mobject-ref.hpp
|
||||
** A reference handle pointing at an MObject, attached (placed) to the session.
|
||||
** Allows client code to access both the object and the placement, even from a
|
||||
** separate Layer or from within plugin code.
|
||||
** External MObject/Placement reference.
|
||||
** This smart-handle referres to an MObject, attached (placed) into the session.
|
||||
** It is a copyable value object, implemented by an LUID (hash) and an shared_ptr.
|
||||
** Holding an MObject ref keeps the referred MObject alive, but gives no guarantees
|
||||
** regarding the validity of the referred \em Placement within the session. On each
|
||||
** access, the placement is re-fetched using the PlacementIndex, which may fail.
|
||||
**
|
||||
** MObjectRef allows to access the pointee (MObject subclass) by using the dereferentiation
|
||||
** operator, and it allows to access the Placement within the session. Moreover, as an
|
||||
** convenience shortcut, some of Placement's query operations are directly exposed.
|
||||
**
|
||||
** !Lifecycle
|
||||
** An MObjectRef is always created inactive. It needs to be activated explicitly,
|
||||
** providing either a direct (language) ref to an Placement within the session,
|
||||
** or an PlacementRef tag, or another MObjecRef. It can be closed (detached).
|
||||
**
|
||||
** !Type handling
|
||||
** Like any smart-ptr MObjectRef is templated on the actual type of the pointee.
|
||||
** It can be built or re-assigned from a variety of sources, given the runtime type
|
||||
** of the referred pointee is compatible to this template parameter type. This
|
||||
** allows flexibly to re-gain a specifically typed context, even based just
|
||||
** on a plain LUID. This functionality is implemented by accessing the
|
||||
** PlacementIndex within the session, and then by using the RTTI of
|
||||
** the fetched Placement's pointee.
|
||||
**
|
||||
** @see MObject
|
||||
** @see Session
|
||||
|
|
@ -39,24 +60,23 @@
|
|||
#define MOBJECT_MOBJECT_REF_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
//#include "proc/mobject/session/locatingpin.hpp"
|
||||
//#include "proc/asset/pipe.hpp"
|
||||
#include "lib/handle.hpp"
|
||||
#include "lib/lumitime.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
|
||||
///////////////////////////////////////////TODO: define an C-API representation here, make the header multilingual!
|
||||
|
||||
namespace mobject {
|
||||
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
class MObject;
|
||||
|
||||
|
||||
LUMIERA_ERROR_DECLARE (BOTTOM_MOBJECTREF); ///< NIL MObjectRef encountered
|
||||
|
||||
/**
|
||||
* An active (smart-ptr like) external reference
|
||||
* to a specifically placed MObject "instance" within the session.
|
||||
|
|
@ -69,29 +89,43 @@ namespace mobject {
|
|||
class MORef
|
||||
: public lib::Handle<MO>
|
||||
{
|
||||
typedef lib::Handle<MO> _Par;
|
||||
typedef lib::Handle<MO> _Handle;
|
||||
|
||||
|
||||
PlacementRef<MO> pRef_;
|
||||
using _Handle::smPtr_;
|
||||
|
||||
PlacementRef<MO> pRef_; ////////////////////////////////////////////////////////////////////TODO: how to create an "inactive" PlacementRef???
|
||||
|
||||
using _Par::smPtr_;
|
||||
|
||||
public:
|
||||
|
||||
MO*
|
||||
operator-> () const
|
||||
{
|
||||
REQUIRE (pRef_ && smPtr_, "Lifecycle-Error: not activated");
|
||||
if (!smPtr_)
|
||||
throw lumiera::error::State("Lifecycle error: MObject ref not activated"
|
||||
,LUMIERA_ERROR_BOTTOM_MOBJECTREF);
|
||||
|
||||
ENSURE (INSTANCEOF (MO, smPtr_.get()));
|
||||
return smPtr_.operator-> ();
|
||||
}
|
||||
|
||||
Placement<MO>& getPlacement() const
|
||||
{
|
||||
REQUIRE (pRef_ && smPtr_, "Lifecycle-Error: not activated");
|
||||
ENSURE (INSTANCEOF (MO, smPtr_.get()));
|
||||
return *pRef_;
|
||||
}
|
||||
|
||||
/** resolves the referred placement to an
|
||||
* ExplicitPlacement and returns the found start time
|
||||
*/
|
||||
lumiera::Time const&
|
||||
getStartTime()
|
||||
{
|
||||
return pRef_.resolve().time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* === Lifecycle === */
|
||||
|
||||
|
|
@ -119,7 +153,7 @@ namespace mobject {
|
|||
* - a plain LUID
|
||||
* @throws error::Invalid when the (directly or indirectly
|
||||
* referred placement isn't known to the session PlacementIndex,
|
||||
* or when the placement actually found has an incompatible dynamic type
|
||||
* or when the placement actually found has an incompatible dynamic type
|
||||
*/
|
||||
template<typename REF>
|
||||
MORef&
|
||||
|
|
@ -153,16 +187,46 @@ namespace mobject {
|
|||
return activate (oRef.getPlacement().getID());
|
||||
}
|
||||
|
||||
/** cross assignment.
|
||||
* @note besides that, we use the default generated copy operations.
|
||||
* @note STRONG exception safety guarantee
|
||||
* @throws error::Invalid when the referred placement isn't registered
|
||||
* within the current session, or if the runtime type of the pointees
|
||||
* aren't assignment compatible
|
||||
*/
|
||||
template<typename MOX>
|
||||
MORef&
|
||||
operator= (MORef<MOX> const& oRef)
|
||||
{
|
||||
return activate (oRef);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* == diagnostics == */
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return pRef_.isValid();
|
||||
}
|
||||
|
||||
size_t
|
||||
use_count() const
|
||||
{
|
||||
return pRef_.use_count();
|
||||
}
|
||||
|
||||
|
||||
template<class MOX>
|
||||
bool
|
||||
isCompatible() const
|
||||
{
|
||||
return pRef_
|
||||
&& (*pRef_).isCompatible<MOX>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* == equality comparisons == */
|
||||
|
||||
|
|
@ -221,7 +285,6 @@ namespace mobject {
|
|||
}
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
typedef MORef<MObject> MObjectRef;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace test {
|
|||
using session::SessionServiceMockIndex;
|
||||
using session::PPIdx;
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* @test properties and behaviour of the external reference-mechanism for
|
||||
|
|
@ -116,7 +116,6 @@ namespace test {
|
|||
PlacementRef<MObject> ref2 (pClip2);
|
||||
|
||||
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 384 !!!!!!!!!
|
||||
// -----Tests------------------
|
||||
checkBuildMObjectRef (rP1, &pClip1);
|
||||
checkBuildMObjectRef (rP2, &pClip2);
|
||||
|
|
@ -131,7 +130,6 @@ namespace test {
|
|||
checkLifecycle (rP1,rP2);
|
||||
checkTypeHandling (luid);
|
||||
// -----Tests------------------
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
|
||||
// verify clean state
|
||||
index->remove (pClip1);
|
||||
|
|
@ -168,30 +166,28 @@ namespace test {
|
|||
|
||||
// access the Placement-API
|
||||
ASSERT (3 == rMO.use_count()); // now rMO shares ownership with the Placement
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 384 !!!!!!!!!
|
||||
ASSERT (0 < rMO.getStartTime()); // (internally, this resolves to an ExplicitPlacement) /////////TICKET #332
|
||||
ASSERT (Time(0) < rMO.getStartTime()); // (internally, this resolves to an ExplicitPlacement) /////////TICKET #332
|
||||
ASSERT ( rMO.isCompatible<MObject>());
|
||||
ASSERT ( rMO.isCompatible<Clip>());
|
||||
ASSERT (!rMO.isCompatible<TestSubMO1>());
|
||||
Time start = rMO.getStartTime();
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
|
||||
// re-link to the Placement (note we get the Clip API!)
|
||||
Placement<Clip> & refP = rMO.getPlacement();
|
||||
ASSERT (refP);
|
||||
ASSERT (refP.isValid());
|
||||
ASSERT (3 == refP.use_count());
|
||||
ASSERT (&refP == placementAdr); // actually denotes the address of the original Placement in the "session"
|
||||
cout << string(refP) << endl;
|
||||
|
||||
ExplicitPlacement exPla = refP.resolve();
|
||||
// ASSERT (exPla.time == start); // recovered Placement resolves to the same time as provided by the proxied API
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
checkComparison (PMO& p1, PMO& p2)
|
||||
checkComparison (PMO const& p1, PMO const& p2)
|
||||
{
|
||||
PlacementRef<Clip> pRef1 (p1);
|
||||
PlacementRef<MObject> pRef2 (p2);
|
||||
|
|
@ -258,7 +254,7 @@ namespace test {
|
|||
|
||||
|
||||
void
|
||||
checkLifecylce (PMObj const& p1, PMObj const& p2)
|
||||
checkLifecycle (PMObj const& p1, PMObj const& p2)
|
||||
{
|
||||
ASSERT (2 == p1.use_count());
|
||||
ASSERT (2 == p2.use_count());
|
||||
|
|
@ -290,7 +286,7 @@ namespace test {
|
|||
ASSERT (2 == p2.use_count());
|
||||
|
||||
VERIFY_ERROR (INVALID_PLACEMENTREF, rMO.getPlacement() );
|
||||
// VERIFY_ERROR (INVALID_MOBJECTREF, rMO->getMedia() );
|
||||
VERIFY_ERROR (BOTTOM_MOBJECTREF, rMO->getMedia() );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -316,9 +312,7 @@ namespace test {
|
|||
|
||||
// impossible, because Clip isn't a subclass of TestSubMO1:
|
||||
VERIFY_ERROR (INVALID_PLACEMENTREF, rSub1.activate(luid) );
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 384 !!!!!!!!!
|
||||
// VERIFY_ERROR (INVALID_PLACEMENTREF, rSub1 = rMObj );
|
||||
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
|
||||
VERIFY_ERROR (INVALID_PLACEMENTREF, rSub1 = rMObj );
|
||||
|
||||
ASSERT (rMObj->isValid());
|
||||
ASSERT (rClip->isValid());
|
||||
|
|
@ -327,12 +321,12 @@ namespace test {
|
|||
// doesn't compile, because the function isn't on MObject API:
|
||||
// rMObj->getMedia();
|
||||
|
||||
// can assign, because the actual type is relevant:
|
||||
rClip.close();
|
||||
ASSERT (3 == rMObj.use_count());
|
||||
ASSERT (0 == rClip.use_count());
|
||||
|
||||
// rClip = rMObj;
|
||||
// can assign, because the actual type checked:
|
||||
rClip = rMObj;
|
||||
ASSERT (4 == rMObj.use_count());
|
||||
ASSERT (4 == rClip.use_count());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue