Clean up design of ScopeQuery, throw out Iterator mixin (closes #641)
This commit is contained in:
parent
4f6fa69f2b
commit
c80b1894e6
6 changed files with 102 additions and 79 deletions
|
|
@ -99,7 +99,7 @@ namespace session {
|
|||
inline typename ScopeQuery<MO>::iterator
|
||||
ScopeLocator::explore (Scope scope)
|
||||
{
|
||||
return ScopeQuery<MO> (theResolver(), scope.getTop(), CHILDREN);
|
||||
return ScopeQuery<MO> (scope.getTop(), CHILDREN).resolveBy (theResolver());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ namespace session {
|
|||
inline typename ScopeQuery<MO>::iterator
|
||||
ScopeLocator::query (Scope scope)
|
||||
{
|
||||
return ScopeQuery<MO> (theResolver(), scope.getTop(), CONTENTS);
|
||||
return ScopeQuery<MO> (scope.getTop(), CONTENTS).resolveBy (theResolver());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ namespace session {
|
|||
inline typename ScopeQuery<MO>::iterator
|
||||
ScopeLocator::locate (Scope scope)
|
||||
{
|
||||
return ScopeQuery<MO> (theResolver(), scope.getTop(), PATH);
|
||||
return ScopeQuery<MO> (scope.getTop(), PATH).resolveBy (theResolver());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -59,15 +59,16 @@ namespace session {
|
|||
|
||||
|
||||
/**
|
||||
* Mix-in ABC, combining a Query for placement-attached objects
|
||||
* with an embedded result set iterator. Thus, an concrete (derived)
|
||||
* DiscoveryQuery can be created by the invoking client code, and
|
||||
* then immediately explored until exhaustion of the result iterator.
|
||||
* ABC to build Queries for placement-attached objects.
|
||||
* The Placements obtained from such a query are typed to the
|
||||
* specific MObject type given as template parameter. To ensure
|
||||
* this, an additional ContentFilter is applied on the yielded
|
||||
* results; this filter function is constructed by a virtual
|
||||
* call when actually issuing the query.
|
||||
*/
|
||||
template<class MO>
|
||||
class DiscoveryQuery
|
||||
: public Query<Placement<MO> >
|
||||
, public Query<Placement<MO> >::iterator
|
||||
{
|
||||
typedef Query<Placement<MO> > _Query;
|
||||
|
||||
|
|
@ -93,7 +94,6 @@ namespace session {
|
|||
|
||||
DiscoveryQuery ()
|
||||
: _Query (_Query::defineQueryTypeID (Goal::DISCOVERY))
|
||||
, _QIter ()
|
||||
{ }
|
||||
|
||||
private:
|
||||
|
|
@ -143,7 +143,6 @@ namespace session {
|
|||
typedef Query<Placement<MO> > _Query;
|
||||
|
||||
|
||||
QueryResolver const& index_;
|
||||
PlacementMO::ID startPoint_;
|
||||
ScopeQueryKind to_discover_;
|
||||
|
||||
|
|
@ -152,24 +151,14 @@ namespace session {
|
|||
typedef typename _Parent::ContentFilter ContentFilter;
|
||||
|
||||
|
||||
ScopeQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope,
|
||||
ScopeQuery (PlacementMO const& scope,
|
||||
ScopeQueryKind direction)
|
||||
: index_(resolver)
|
||||
, startPoint_(scope)
|
||||
: startPoint_(scope)
|
||||
, to_discover_(direction)
|
||||
{
|
||||
resetResultIteration (_Query::resolveBy(index_)); ///////////////////////////////TICKET #642 this call causes the problem!!!
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
iterator
|
||||
operator() () const
|
||||
{
|
||||
return _Query::resolveBy (index_);
|
||||
}
|
||||
|
||||
PlacementMO::ID const&
|
||||
searchScope () const
|
||||
{
|
||||
|
|
@ -209,9 +198,8 @@ namespace session {
|
|||
struct ContentsQuery
|
||||
: ScopeQuery<MO>
|
||||
{
|
||||
ContentsQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope)
|
||||
: ScopeQuery<MO> (resolver,scope, CONTENTS)
|
||||
ContentsQuery (PlacementMO const& scope)
|
||||
: ScopeQuery<MO> (scope, CONTENTS)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
|
@ -221,9 +209,8 @@ namespace session {
|
|||
struct PathQuery
|
||||
: ScopeQuery<MO>
|
||||
{
|
||||
PathQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope)
|
||||
: ScopeQuery<MO> (resolver,scope, PARENTS)
|
||||
PathQuery (PlacementMO const& scope)
|
||||
: ScopeQuery<MO> (scope, PARENTS)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
|
@ -233,18 +220,25 @@ namespace session {
|
|||
class SpecificContentsQuery
|
||||
: public ContentsQuery<MO>
|
||||
{
|
||||
typedef ContentsQuery<MO> _Parent;
|
||||
typedef typename _Parent::ContentFilter ContentFilter;
|
||||
typedef typename ContentsQuery<MO>::ContentFilter ContentFilter;
|
||||
|
||||
typedef Placement<MO> const& TypedPlacement;
|
||||
|
||||
typedef function<bool(TypedPlacement)> SpecialPredicate;
|
||||
|
||||
class SpecialTest
|
||||
/**
|
||||
* Filter functor, built on top of a predicate,
|
||||
* which is provided by the client on creation of this
|
||||
* SpecivicContentsQuery instance. This allows for filtering
|
||||
* based on operations of the specific type MO, as opposed to
|
||||
* just using the bare MObject interface.
|
||||
*/
|
||||
class Filter
|
||||
{
|
||||
SpecialPredicate predicate_;
|
||||
|
||||
public:
|
||||
SpecialTest (SpecialPredicate const& pred)
|
||||
Filter (SpecialPredicate const& pred)
|
||||
: predicate_(pred)
|
||||
{ }
|
||||
|
||||
|
|
@ -259,8 +253,14 @@ namespace session {
|
|||
}
|
||||
};
|
||||
|
||||
SpecialTest specialTest_;
|
||||
Filter specialTest_;
|
||||
|
||||
/** using a specialised version of the filtering,
|
||||
* which doesn't only check the concrete type,
|
||||
* but also applies a custom filter predicate
|
||||
* @return function object, embedding a copy
|
||||
* of the Filter functor.
|
||||
*/
|
||||
ContentFilter
|
||||
buildContentFilter() const
|
||||
{
|
||||
|
|
@ -268,10 +268,9 @@ namespace session {
|
|||
}
|
||||
|
||||
public:
|
||||
SpecificContentsQuery (QueryResolver const& resolver
|
||||
,PlacementMO const& scope
|
||||
SpecificContentsQuery (PlacementMO const& scope
|
||||
,SpecialPredicate const& specialPred)
|
||||
: ContentsQuery<MO> (resolver,scope)
|
||||
: ContentsQuery<MO> (scope)
|
||||
, specialTest_(specialPred)
|
||||
{ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -142,17 +142,20 @@ out: Placement<.+TestSubMO1.>
|
|||
out: --------------------------------Test-5: contents depth-first, filtered to TestSubMO2
|
||||
out: Placement<.+TestSubMO21.>
|
||||
out: Placement<.+TestSubMO2.>
|
||||
out: --------------------------------Test-6: parents of the second TestSubMO2 element found
|
||||
out: --------------------------------Test-6: contents depth-first, custom filtered DummyMO
|
||||
out: Placement<.+TestSubMO21.>
|
||||
out: Placement<.+TestSubMO2.>
|
||||
out: --------------------------------Test-7: parents of the second TestSubMO2 element found
|
||||
out: Placement<.+TestSubMO21.>
|
||||
out: Placement<.+mobject.session.Label.>
|
||||
out: --------------------------------Test-7: children of the this TestSubMO2 element
|
||||
out: --------------------------------Test-8: children of the this TestSubMO2 element
|
||||
out: Placement<.+TestSubMO21.>
|
||||
out: --------------------------------Test-8: path from there to root
|
||||
out: --------------------------------Test-9: path from there to root
|
||||
out: Placement<.+TestSubMO21.>
|
||||
out: Placement<.+mobject.session.Label.>
|
||||
out: --------------------------------Test-9: same path, but filtered to TestSubMO2
|
||||
out: --------------------------------Test-10: same path, but filtered to TestSubMO2
|
||||
out: Placement<.+TestSubMO21.>
|
||||
out: --------------------------------Test-10: continue exploring partially used TestSubMO2 iterator
|
||||
out: --------------------------------Test-11: continue exploring partially used TestSubMO2 iterator
|
||||
out: Placement<.+TestSubMO21.>
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace test {
|
|||
PlacementMO& root2 = SessionServiceExploreScope::getScopeRoot();
|
||||
ASSERT (isSameObject (root1, root2));
|
||||
|
||||
PlacementMO& elm1 = *ContentsQuery<TestSubMO21>(resolver1,root1);
|
||||
PlacementMO& elm1 = *ContentsQuery<TestSubMO21>(root1).resolveBy(resolver1);
|
||||
PlacementMO& elm2 = *(index->getReferrers(root1));
|
||||
ASSERT (isSameObject (elm1, elm2));
|
||||
}
|
||||
|
|
@ -93,12 +93,12 @@ namespace test {
|
|||
PlacementIndexQueryResolver resolver(*index);
|
||||
|
||||
cout << "explore contents depth-first..." << endl;
|
||||
discover (ContentsQuery<MObject> (resolver,root));
|
||||
discover (ContentsQuery<MObject>(root).resolveBy(resolver));
|
||||
|
||||
PlacementMO& elm = *ContentsQuery<TestSubMO1>(resolver,root); ////////////////////// TICKET #532
|
||||
PlacementMO& elm = *ContentsQuery<TestSubMO1>(root).resolveBy(resolver); ////////////////////// TICKET #532
|
||||
|
||||
cout << "path to root starting at " << string(elm) << endl;
|
||||
discover (PathQuery<MObject> (resolver,elm));
|
||||
discover (PathQuery<MObject> (elm).resolveBy(resolver));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "proc/mobject/session/test-scopes.hpp"
|
||||
#include "proc/mobject/session/clip.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
|
@ -41,14 +42,37 @@ namespace test {
|
|||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
namespace {
|
||||
|
||||
using util::contains;
|
||||
|
||||
|
||||
namespace { // helpers and shortcuts....
|
||||
|
||||
/** a filter predicate to pick some objects from a resultset.
|
||||
* @note using the specific API of DummyMO, without cast! */
|
||||
bool
|
||||
filterfunk (Placement<DummyMO> const& candidate)
|
||||
filter (Placement<DummyMO> const& candidate)
|
||||
{
|
||||
string desc = candidate->operator string();
|
||||
cout << "prüfe..." << desc << endl;
|
||||
return desc == "TestSubMO2";
|
||||
return contains(desc, "MO2");
|
||||
}
|
||||
|
||||
template<class IT>
|
||||
void
|
||||
pullOut (IT const& iter)
|
||||
{
|
||||
for (IT elm(iter);
|
||||
elm; ++elm)
|
||||
cout << string(*elm) << endl;
|
||||
}
|
||||
|
||||
void
|
||||
announce (Literal description)
|
||||
{
|
||||
static uint nr(0);
|
||||
cout << "--------------------------------Test-"<< ++nr << ": " << description << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -74,46 +98,43 @@ namespace test {
|
|||
// Prepare an (test)Index (dummy "session")
|
||||
PPIdx testSession (build_testScopes());
|
||||
|
||||
QueryResolver const& resolver = SessionServiceExploreScope::getResolver();
|
||||
PlacementMO const& scope = SessionServiceExploreScope::getScopeRoot();
|
||||
PlacementMO const& scope = SessionServiceExploreScope::getScopeRoot();
|
||||
|
||||
discover (ScopeQuery<MObject> (resolver,scope, CONTENTS) , "contents depth-first");
|
||||
discover (ScopeQuery<Clip> (resolver,scope, CONTENTS) , "contents depth-first, filtered to Clip");
|
||||
discover (ScopeQuery<DummyMO> (resolver,scope, CONTENTS) , "contents depth-first, filtered to DummyMO"); ////////////////////// TICKET #532
|
||||
discover (ScopeQuery<TestSubMO1> (resolver,scope, CONTENTS) , "contents depth-first, filtered to TestSubMO1");
|
||||
discover (ScopeQuery<TestSubMO2> (resolver,scope, CONTENTS) , "contents depth-first, filtered to TestSubMO2");
|
||||
|
||||
discover (SpecificContentsQuery<DummyMO> (resolver,scope, &filterfunk) , "contents depth-first, custom filtered DummyMO");
|
||||
discover (ScopeQuery<MObject> (scope, CONTENTS) , "contents depth-first");
|
||||
discover (ScopeQuery<Clip> (scope, CONTENTS) , "contents depth-first, filtered to Clip");
|
||||
discover (ScopeQuery<DummyMO> (scope, CONTENTS) , "contents depth-first, filtered to DummyMO"); ////////////////////// TICKET #532
|
||||
discover (ScopeQuery<TestSubMO1> (scope, CONTENTS) , "contents depth-first, filtered to TestSubMO1");
|
||||
discover (ScopeQuery<TestSubMO2> (scope, CONTENTS) , "contents depth-first, filtered to TestSubMO2");
|
||||
|
||||
ScopeQuery<TestSubMO21> specialEl(resolver,scope, CONTENTS);
|
||||
discover (SpecificContentsQuery<DummyMO> (scope, filter) , "contents depth-first, custom filtered DummyMO");
|
||||
|
||||
ScopeQuery<TestSubMO21> allM021(scope, CONTENTS);
|
||||
ScopeQuery<TestSubMO21>::iterator specialEl (issue(allM021));
|
||||
++specialEl; // step in to second solution found...
|
||||
ASSERT (specialEl);
|
||||
|
||||
discover (ScopeQuery<MObject> (resolver,*specialEl, PARENTS) , "parents of the second TestSubMO2 element found");
|
||||
discover (ScopeQuery<MObject> (resolver,*specialEl, CHILDREN), "children of the this TestSubMO2 element");
|
||||
discover (ScopeQuery<MObject> (resolver,*specialEl, PATH) , "path from there to root");
|
||||
discover (ScopeQuery<TestSubMO2> (resolver,*specialEl, PATH) , "same path, but filtered to TestSubMO2");
|
||||
discover (specialEl , "continue exploring partially used TestSubMO2 iterator");
|
||||
discover (ScopeQuery<MObject> (*specialEl, PARENTS) , "parents of the second TestSubMO2 element found");
|
||||
discover (ScopeQuery<MObject> (*specialEl, CHILDREN), "children of the this TestSubMO2 element");
|
||||
discover (ScopeQuery<MObject> (*specialEl, PATH) , "path from there to root");
|
||||
discover (ScopeQuery<TestSubMO2> (*specialEl, PATH) , "same path, but filtered to TestSubMO2");
|
||||
announce ( "continue exploring partially used TestSubMO2 iterator");
|
||||
pullOut (specialEl);
|
||||
}
|
||||
|
||||
|
||||
template<class MO>
|
||||
void
|
||||
static void
|
||||
discover (ScopeQuery<MO> const& query, Literal description)
|
||||
{
|
||||
typedef typename ScopeQuery<MO>::iterator I;
|
||||
|
||||
announce (description);
|
||||
for (I elm(query);
|
||||
elm; ++elm)
|
||||
cout << string(*elm) << endl;
|
||||
pullOut (issue(query));
|
||||
}
|
||||
|
||||
void
|
||||
announce (Literal description)
|
||||
template<class MO>
|
||||
static typename ScopeQuery<MO>::iterator
|
||||
issue (ScopeQuery<MO> const& query)
|
||||
{
|
||||
static uint nr(0);
|
||||
cout << "--------------------------------Test-"<< ++nr << ": " << description << endl;
|
||||
return query.resolveBy(SessionServiceExploreScope::getResolver());
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -78,16 +78,16 @@ namespace test {
|
|||
PlacementMO&
|
||||
retrieve_startElm()
|
||||
{
|
||||
return *ContentsQuery<TestSubMO1>(SessionServiceExploreScope::getResolver()
|
||||
,SessionServiceExploreScope::getScopeRoot());
|
||||
return *ContentsQuery<TestSubMO1>(SessionServiceExploreScope::getScopeRoot())
|
||||
.resolveBy(SessionServiceExploreScope::getResolver());
|
||||
}
|
||||
|
||||
|
||||
ScopeQuery<MObject>::iterator
|
||||
explore_testScope (PlacementMO const& scopeTop)
|
||||
{
|
||||
return ScopeQuery<MObject>(SessionServiceExploreScope::getResolver(),
|
||||
scopeTop, CHILDREN);
|
||||
return ScopeQuery<MObject>(scopeTop, CHILDREN)
|
||||
.resolveBy(SessionServiceExploreScope::getResolver());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue