PlacementIndex implemented, unit test pass
This commit is contained in:
parent
96f19c656d
commit
14c7f7fc62
7 changed files with 82 additions and 69 deletions
|
|
@ -78,7 +78,7 @@ namespace asset
|
|||
/** use another wiring template. Triggers complete rebuild of the render engine. */
|
||||
void switchProcPatt (PProcPatt& another);
|
||||
|
||||
/** convienience shortcut for retrieving default configured pipes */
|
||||
/** convenience shortcut for retrieving default configured pipes */
|
||||
static PPipe query (string properties) ;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
**
|
||||
** @todo this can be considered a preliminary sketch without being backed
|
||||
** by actual functionality. Just enough to be able to drive the design of
|
||||
** other parts ahead. See esp. Trac #100, which contains an idea for a
|
||||
** other parts ahead. See esp. TICKET #100, which contains an idea for a
|
||||
** refactoring.
|
||||
**
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
|
||||
/** @file placement-index.cpp
|
||||
** Implementation of core session storage structure.
|
||||
** The PlacementIndex associates IDs to instances, and nested scope structure.
|
||||
** The PlacementIndex associates IDs to instances, within a nested scope structure.
|
||||
** Moreover, it provides and manages the actual Placement instances (storage),
|
||||
** considered to be part of the session.
|
||||
** considered to be part of the session.
|
||||
**
|
||||
** Simple hash based implementation. Seems adequate for now (12/09).
|
||||
** A main table associates Placement-ID to an Placement \em instance, which is contained
|
||||
|
|
@ -34,15 +34,15 @@
|
|||
** by wrapping up an STL iterator range into a "Lumiera Forward Iterator" (adapter).
|
||||
** Generally speaking, PlacementIndex is an implementation level facility and provides
|
||||
** the basic/low-level functionality. For example, the PlacementIndexQueryResolver
|
||||
** provides depth-first exploration of all the contents of an scope, including nested scopes,
|
||||
** building on top of these scope iterators from PlacementIndex.
|
||||
** provides depth-first exploration of all the contents of an scope, including
|
||||
** nested scopes, building on top of the scope iterators from PlacementIndex.
|
||||
**
|
||||
** PlacementIndex can be seen as the core datastructure of the session. Objects are attached
|
||||
** to the session by adding (copying) a Placement instance, which is owned and managed by
|
||||
** the PlacementIndex. Adding this Placement instance creates a new Placement-ID, which
|
||||
** from then on acts as a shorthand for "the object instance" within the session.
|
||||
** from then on acts as a shorthand for "the object instance" within the session.
|
||||
** The actual storage is provided by an embedded TypedAllocationManager instance, which
|
||||
** is planned (as of 12/09) to be backed later by a memory pool based custom allocator.
|
||||
** is planned (as of 12/09) to be backed later by a memory pool based custom allocator.
|
||||
**
|
||||
** @see PlacementRef
|
||||
** @see PlacementIndex_test
|
||||
|
|
@ -54,29 +54,25 @@
|
|||
#include "proc/mobject/session/session-impl.hpp"
|
||||
#include "proc/mobject/session/scope.hpp"
|
||||
#include "lib/typed-allocation-manager.hpp"
|
||||
//#include "proc/mobject/mobject.hpp" ///////////////////////TODO necessary?
|
||||
#include "lib/util-foreach.hpp"
|
||||
#include "lib/iter-source.hpp"
|
||||
#include "include/logging.h"
|
||||
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
//using boost::str;
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <tr1/unordered_map>
|
||||
#include <tr1/functional>
|
||||
#include <tr1/memory>
|
||||
//#include <algorithm>
|
||||
#include <string>
|
||||
//#include <map>
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
|
||||
|
||||
using boost::hash;
|
||||
using boost::noncopyable;
|
||||
using boost::lambda::var;
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::unordered_map;
|
||||
using std::tr1::unordered_multimap;
|
||||
|
|
@ -84,9 +80,6 @@ namespace session {
|
|||
using std::tr1::placeholders::_1;
|
||||
using std::tr1::function;
|
||||
using std::tr1::bind;
|
||||
//using util::contains;
|
||||
//using std::string;
|
||||
//using std::map;
|
||||
using std::make_pair;
|
||||
using std::pair;
|
||||
|
||||
|
|
@ -98,7 +91,7 @@ namespace session {
|
|||
LUMIERA_ERROR_DEFINE (NOT_IN_SESSION, "referring to a Placement not known to the current session");
|
||||
LUMIERA_ERROR_DEFINE (PLACEMENT_TYPE, "requested Placement (pointee) type not compatible with data or context");
|
||||
LUMIERA_ERROR_DEFINE (NONEMPTY_SCOPE, "Placement scope (still) contains other elements");
|
||||
|
||||
|
||||
|
||||
|
||||
/* some type shorthands */
|
||||
|
|
@ -107,7 +100,7 @@ namespace session {
|
|||
typedef PlacementIndex::ID ID;
|
||||
|
||||
|
||||
/**
|
||||
/*********************************************************************
|
||||
* Storage and implementation backing the PlacementIndex
|
||||
* - #placementTab_ is an hashtable mapping IDs to Placement + Scope
|
||||
* - #scopeTab_ is an reverse association serving to keep track of
|
||||
|
|
@ -139,7 +132,7 @@ namespace session {
|
|||
PPlacement root_;
|
||||
|
||||
public:
|
||||
Table ()
|
||||
Table ()
|
||||
{ }
|
||||
|
||||
~Table ()
|
||||
|
|
@ -173,13 +166,14 @@ namespace session {
|
|||
{
|
||||
return allocator_.numSlots<PlacementMO>();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
contains (ID id) const
|
||||
{
|
||||
return util::contains(placementTab_, id);
|
||||
}
|
||||
|
||||
|
||||
PlacementMO&
|
||||
fetch (ID id) const
|
||||
{
|
||||
|
|
@ -233,7 +227,6 @@ namespace session {
|
|||
{
|
||||
REQUIRE (0 == placementTab_.size());
|
||||
REQUIRE (0 == scopeTab_.size());
|
||||
REQUIRE (!root_);
|
||||
|
||||
root_ = allocator_.create<PlacementMO> (rootDef);
|
||||
ID rootID = root_->getID();
|
||||
|
|
@ -257,12 +250,12 @@ namespace session {
|
|||
|
||||
|
||||
/** Store a copy of the given Placement as new instance
|
||||
* within the index, together with the Scope this Placement
|
||||
* belongs to.
|
||||
* within the index, together with the Scope
|
||||
* this Placement belongs to.
|
||||
* @note we discard the specific type info.
|
||||
* It can be rediscovered later with the help
|
||||
* of the pointee's vtable
|
||||
* @see Placement#isCompatible
|
||||
* @see Placement#isCompatible
|
||||
*/
|
||||
ID
|
||||
addEntry (PlacementMO const& newObj, ID scopeID)
|
||||
|
|
@ -308,7 +301,7 @@ namespace session {
|
|||
|
||||
typedef lib::IterSource<PID>::iterator IDIter;
|
||||
|
||||
PlacementMO* _root_4check () { return root_.get(); }
|
||||
PlacementMO* _root_4check () { return root_.get(); }
|
||||
PlacementMO* _element_4check (ID id){ return base_entry(id).element.get();}
|
||||
PlacementMO* _scope_4check (ID id) { return base_entry(id).scope.get(); }
|
||||
IDIter _eachEntry_4check () { return eachMapKey (placementTab_); }
|
||||
|
|
@ -323,7 +316,7 @@ namespace session {
|
|||
{
|
||||
Slot pos = placementTab_.find (key);
|
||||
if (pos == placementTab_.end())
|
||||
throw error::Logic("lost a Placement expected to be registered in the index.");
|
||||
throw error::Logic("lost a Placement expected to be registered within PlacementIndex.");
|
||||
|
||||
return pos->second;
|
||||
}
|
||||
|
|
@ -385,6 +378,9 @@ namespace session {
|
|||
}
|
||||
|
||||
};
|
||||
//(End) placement index table implementation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -403,8 +399,8 @@ namespace session {
|
|||
}
|
||||
|
||||
PlacementIndex::~PlacementIndex() { }
|
||||
|
||||
|
||||
|
||||
|
||||
PlacementMO&
|
||||
PlacementIndex::getRoot() const
|
||||
{
|
||||
|
|
@ -433,7 +429,7 @@ namespace session {
|
|||
__check_knownID(*this,id);
|
||||
return pTab_->fetch (id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** retrieve the Scope information
|
||||
|
|
@ -573,13 +569,17 @@ namespace session {
|
|||
VERIFY ( tab.contains (sco(id)->getID()),
|
||||
"(1.7) Elements", "Element associated with an unknown scope");
|
||||
|
||||
PMO* theElement = elm(id);
|
||||
PMO& theElement = *elm(id);
|
||||
ID theScope (sco(id)->getID());
|
||||
if (theScope == id
|
||||
&& elm(id)==tab._root_4check()
|
||||
) // no need to check root,
|
||||
return; // because root is it's own scope
|
||||
|
||||
iterator elementsInScope = tab.queryScopeContents(theScope);
|
||||
bool properlyRegistered = has_any (elementsInScope, _1_ == *theElement );
|
||||
bool properlyRegistered = has_any (elementsInScope, _1_ == var(theElement));
|
||||
|
||||
VERIFY ( properlyRegistered, "(1.8) Elements", "Element isn't registered as member of the enclosing scope");
|
||||
VERIFY ( properlyRegistered, "(1.8) Elements", "Element not registered as member of the enclosing scope: "+ theElement);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -624,7 +624,8 @@ namespace session {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** validity self-check, used for sanity checks and the session self-check.
|
||||
* The following checks are performed (causing at least one full table scan)
|
||||
* - root element exists and is valid.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
** contained within the PlacementIndex. Usually, the commands expressing any mutating
|
||||
** operations on the session, bind MObjectRef instances as arguments; similarly, the
|
||||
** public API functions on the Session interface (and similar facade interfaces) are
|
||||
** written in terms of MObectRef.
|
||||
** written in terms of MObectRef.
|
||||
**
|
||||
** \par placement scopes
|
||||
** When adding a Placement to the index, it is mandatory to specify a Scope: this is
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
** any processing is assumed to happen in a suitable typed context. Consequently,
|
||||
** client code will never need to fetch Placements directly from the index. This
|
||||
** allows all type information to be discarded on adding (copying) a Placement
|
||||
** instances into the PlacementIndex.
|
||||
** instance into the PlacementIndex.
|
||||
**
|
||||
** @note PlacementIndex is <b>not threadsafe</b>.
|
||||
**
|
||||
|
|
@ -106,8 +106,6 @@
|
|||
#define MOBJECT_PLACEMENT_INDEX_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
//#include "proc/mobject/session/locatingpin.hpp"
|
||||
//#include "proc/asset/pipe.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/itertools.hpp"
|
||||
|
|
@ -121,7 +119,7 @@
|
|||
|
||||
|
||||
namespace mobject {
|
||||
|
||||
|
||||
class MObject;
|
||||
|
||||
namespace session {
|
||||
|
|
@ -220,7 +218,7 @@ namespace session {
|
|||
|
||||
/* === forwarding implementations of the templated API === */
|
||||
|
||||
|
||||
|
||||
namespace { // shortcuts...
|
||||
|
||||
template<class MOX>
|
||||
|
|
@ -246,8 +244,8 @@ namespace session {
|
|||
,LUMIERA_ERROR_NOT_IN_SESSION); ///////////////////////TICKET #197
|
||||
}
|
||||
}//(End) shortcuts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class MO>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,16 @@ out: pID\(\w{8,16}\)
|
|||
END
|
||||
|
||||
|
||||
PLANNED "PlacementIndex_test" PlacementIndex_test <<END
|
||||
TEST "PlacementIndex_test" PlacementIndex_test <<END
|
||||
out: ^::Placement<.+session.test.TestClip.+ use-cnt=2
|
||||
out: ^::Placement<.+session.test.TestClip.+ use-cnt=6
|
||||
out: ^ ::Placement<.+session.test.TestClip.+ use-cnt=6
|
||||
out: ^ ::Placement<.+session.test.TestClip.+ use-cnt=6
|
||||
out: ^ ...2 elements at Level 2
|
||||
out: ^ ::Placement<.+session.test.TestClip.+ use-cnt=6
|
||||
out: ^ ...3 elements at Level 1
|
||||
out: ^::Placement<.+session.test.TestClip.+ use-cnt=2
|
||||
out: ^...3 elements at Level 0
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ namespace test {
|
|||
|
||||
hijacked->specialAPI();
|
||||
ASSERT (3 == hijacked.use_count());
|
||||
ASSERT (hijacked.getID() == pSub3.getID());
|
||||
ASSERT (hijacked.getID() == pClip.getID());
|
||||
|
||||
cout << format_PlacementID(pSub1) << endl;
|
||||
cout << format_PlacementID(pSub2) << endl;
|
||||
|
|
|
|||
|
|
@ -23,13 +23,11 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
//#include "proc/asset/media.hpp"
|
||||
//#include "proc/mobject/session.hpp"
|
||||
//#include "proc/mobject/session/edl.hpp"
|
||||
#include "proc/mobject/session/placement-index.hpp"
|
||||
#include "proc/mobject/session/scope.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "proc/mobject/session/testclip.hpp"
|
||||
#include "proc/mobject/session/testroot.hpp"
|
||||
|
||||
|
|
@ -37,8 +35,6 @@
|
|||
#include <iostream>
|
||||
|
||||
using boost::format;
|
||||
//using lumiera::Time;
|
||||
//using util::contains;
|
||||
using util::isSameObject;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
|
@ -48,16 +44,15 @@ using std::endl;
|
|||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
using asset::VIDEO;
|
||||
|
||||
using session::test::TestClip;
|
||||
|
||||
typedef PlacementIndex& Idx;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* @test basic behaviour of the index mechanism used to keep track of
|
||||
* individual Placements as added to the current Session..
|
||||
* @test basic behaviour of the index mechanism used to keep track
|
||||
* of individual Placements as added to the current Session.
|
||||
* @see mobject::Placement
|
||||
* @see mobject::MObject#create
|
||||
* @see mobject::Placement#addPlacement
|
||||
|
|
@ -76,14 +71,14 @@ namespace test {
|
|||
has_size (0, index);
|
||||
|
||||
checkSimpleAccess (index);
|
||||
has_size (1, index);
|
||||
has_size (2, index);
|
||||
|
||||
checkScopeHandling (index);
|
||||
has_size (7, index);
|
||||
has_size (8, index);
|
||||
|
||||
checkContentsEnumeration (index);
|
||||
|
||||
has_size (7, index);
|
||||
has_size (8, index);
|
||||
ASSERT (index.isValid());
|
||||
|
||||
index.clear();
|
||||
|
|
@ -97,6 +92,7 @@ namespace test {
|
|||
ASSERT (siz == index.size());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
checkSimpleInsertRemove (Idx index)
|
||||
{
|
||||
|
|
@ -104,15 +100,17 @@ namespace test {
|
|||
PMO& root = index.getRoot();
|
||||
|
||||
ASSERT (0 == index.size());
|
||||
ASSERT (!index.contains (clip));
|
||||
|
||||
index.insert (clip, root);
|
||||
PMO::ID elmID = index.insert (clip, root);
|
||||
ASSERT (1 == index.size());
|
||||
ASSERT ( index.contains (clip));
|
||||
ASSERT ( index.contains (elmID));
|
||||
ASSERT (!index.contains (clip)); // index stores copies
|
||||
|
||||
index.remove(clip);
|
||||
index.remove(clip); // has no effect
|
||||
ASSERT (1 == index.size());
|
||||
index.remove(elmID);
|
||||
ASSERT (0 == index.size());
|
||||
ASSERT (!index.contains (clip));
|
||||
ASSERT (!index.contains (elmID));
|
||||
ASSERT ( index.contains (root));
|
||||
}
|
||||
|
||||
|
|
@ -127,13 +125,20 @@ namespace test {
|
|||
PMO& elm = index.find(elmID);
|
||||
ASSERT (elmID == elm.getID());
|
||||
ASSERT (!isSameObject (elm,testObj)); // note: placements are registered as copy
|
||||
ASSERT (elm == testObj); // they are semantically equivalent
|
||||
ASSERT (isSameDef(elm,testObj)); // they are semantically equivalent ////////TICKET #511
|
||||
ASSERT (elmID != testObj.getID()); // but have a distinct identity
|
||||
|
||||
PMO::ID elmID2 = index.insert(testObj, root);
|
||||
ASSERT (elmID != elmID); // ...and each insert creates a new instance
|
||||
ASSERT (testObj == index.find(elmID2));
|
||||
ASSERT (elmID2 != elmID); // ...and each insert creates a new instance
|
||||
ASSERT (testObj != index.find (elmID));
|
||||
ASSERT (testObj != index.find (elmID2));
|
||||
ASSERT (isSameDef(testObj, index.find(elmID)));
|
||||
ASSERT (isSameDef(testObj, index.find(elmID2)));
|
||||
ASSERT (!isSameObject (testObj, index.find(elmID2)));
|
||||
ASSERT (!isSameObject (elm, index.find(elmID2)));
|
||||
|
||||
// can repeatedly retrieve a reference to the same object
|
||||
ASSERT ( isSameObject (elm, index.find(elmID )));
|
||||
ASSERT ( isSameObject (elm, index.find(elmID )));
|
||||
|
||||
// can also re-access objects by previous ref
|
||||
|
|
@ -200,7 +205,7 @@ namespace test {
|
|||
ASSERT (!index.contains(e1331));
|
||||
ASSERT (!index.remove(e1331));
|
||||
|
||||
ASSERT (index.remove(e133)); // but can remove an scope, after emptying it
|
||||
ASSERT (index.remove(e133)); // but can remove an scope, after emptying it
|
||||
ASSERT (!index.contains(e133));
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +214,7 @@ namespace test {
|
|||
typedef PlacementIndex::iterator Iter;
|
||||
|
||||
/** @test drill down into the tree-like structure
|
||||
* and enumerate the contents of each element, if any
|
||||
* and enumerate the contents of each element, if any
|
||||
*/
|
||||
void
|
||||
checkContentsEnumeration (Idx index)
|
||||
|
|
@ -254,6 +259,6 @@ namespace test {
|
|||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (PlacementIndex_test, "unit session");
|
||||
|
||||
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
|
|||
Loading…
Reference in a new issue