WIP refactor ContentsQuery to share implementation with a PathQuery facility
This commit is contained in:
parent
bdb8bc2c98
commit
78f9b2b1c5
7 changed files with 394 additions and 34 deletions
212
src/proc/mobject/session/placement-index-query-resolver.hpp
Normal file
212
src/proc/mobject/session/placement-index-query-resolver.hpp
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
PLACEMENT-INDEX.hpp - tracking individual Placements and their relations
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file placement-index.hpp
|
||||
**
|
||||
** @see PlacementRef
|
||||
** @see PlacementIndex_test
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef MOBJECT_PLACEMENT_INDEX_H
|
||||
#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/factory.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/placement-ref.hpp"
|
||||
#include "proc/mobject/session/query-resolver.hpp"
|
||||
|
||||
#include <tr1/memory>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace mobject {
|
||||
|
||||
class MObject;
|
||||
|
||||
namespace session {
|
||||
|
||||
using lib::factory::RefcountFac;
|
||||
using std::tr1::shared_ptr;
|
||||
using boost::scoped_ptr;
|
||||
using std::vector;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
class PlacementIndex
|
||||
: public session::QueryResolver ////////TODO: really inherit here?
|
||||
// , boost::noncopyable ////////TODO : where to put the "noncopyable" base
|
||||
{
|
||||
class Table;
|
||||
|
||||
scoped_ptr<Table> pTab_;
|
||||
|
||||
public:
|
||||
typedef Placement<MObject> PlacementMO;
|
||||
typedef PlacementRef<MObject> PRef;
|
||||
typedef PlacementMO::ID const& ID;
|
||||
|
||||
typedef session::Goal::QueryID const& QID;
|
||||
|
||||
|
||||
PlacementMO& find (ID) const;
|
||||
|
||||
template<class MO>
|
||||
Placement<MO>& find (PlacementMO::Id<MO>) const;
|
||||
template<class MO>
|
||||
Placement<MO>& find (PlacementRef<MO> const&) const;
|
||||
|
||||
PlacementMO& getScope (PlacementMO const&) const;
|
||||
PlacementMO& getScope (ID) const;
|
||||
|
||||
vector<PRef> getReferrers (ID) const;
|
||||
|
||||
|
||||
/** retrieve the logical root scope */
|
||||
PlacementMO& getRoot() const;
|
||||
|
||||
size_t size() const;
|
||||
bool contains (PlacementMO const&) const;
|
||||
bool contains (ID) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////TODO: refactor into explicit query resolving wrapper
|
||||
template<class MO>
|
||||
typename session::Query<Placement<MO> >::iterator
|
||||
query (PlacementMO& scope) const;
|
||||
|
||||
operator string() const { return "PlacementIndex"; }
|
||||
////////////////////////////////////////////////////////////////TODO: refactor into explicit query resolving wrapper
|
||||
|
||||
|
||||
bool canHandleQuery(QID) const;
|
||||
|
||||
|
||||
/* == mutating operations == */
|
||||
|
||||
ID insert (PlacementMO& newObj, PlacementMO& targetScope);
|
||||
bool remove (PlacementMO&);
|
||||
bool remove (ID);
|
||||
|
||||
|
||||
typedef RefcountFac<PlacementIndex> Factory;
|
||||
|
||||
static Factory create;
|
||||
|
||||
~PlacementIndex();
|
||||
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
PlacementIndex() ;
|
||||
|
||||
friend class lib::factory::Factory<PlacementIndex, lib::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...
|
||||
|
||||
|
||||
typedef shared_ptr<PlacementIndex> PPIdx;
|
||||
|
||||
|
||||
|
||||
/** @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. */
|
||||
void
|
||||
reset_PlacementIndex(PPIdx const&) ;
|
||||
|
||||
/** @internal restore the implicit PlacementIndex to its default implementation (=the session) */
|
||||
void
|
||||
reset_PlacementIndex() ;
|
||||
|
||||
/** @internal access point for PlacementRef to the implicit global PlacementIndex */
|
||||
Placement<MObject> &
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/** @todo use query-resolver-test as an example.....
|
||||
* return a result set object derived from Resolution
|
||||
* For the additional type filtering: build a filter iterator,
|
||||
* using a type-filtering predicate, based on Placement#isCompatible
|
||||
*/
|
||||
template<class MO>
|
||||
inline typename session::Query<Placement<MO> >::iterator
|
||||
PlacementIndex::query (PlacementMO& scope) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually run the containment query");
|
||||
}
|
||||
|
||||
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::session
|
||||
#endif
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
//#include "proc/mobject/mobject.hpp"
|
||||
#include "proc/mobject/session/scope.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/session/contents-query.hpp"
|
||||
#include "proc/mobject/session/scope-query.hpp"
|
||||
#include "lib/singleton.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/session/query-resolver.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
#include <tr1/functional>
|
||||
|
||||
|
|
@ -34,6 +35,7 @@
|
|||
namespace mobject {
|
||||
namespace session {
|
||||
|
||||
using lib::Literal;
|
||||
using std::tr1::bind;
|
||||
using std::tr1::function;
|
||||
using std::tr1::placeholders::_1;
|
||||
|
|
@ -41,10 +43,10 @@ namespace session {
|
|||
|
||||
|
||||
/**
|
||||
* Query a scope to discover it's contents.
|
||||
* This is a special kind of query, wired up such as to
|
||||
* enumerate the contents of a scope, filtered by a subtype-check.
|
||||
* For the actual resolution of the scope's contents, this query
|
||||
* Query a scope to discover it's contents or location.
|
||||
* This is a special kind of query, wired up such as to enumerate
|
||||
* the contents or parents of a scope, filtered by a subtype-check.
|
||||
* For the actual resolution of the elements to discover, this query
|
||||
* relies on an index like facility (usually Session's PlacementIndex),
|
||||
* which is abstracted as a QueryResolver, but actually is expected to
|
||||
* cooperate especially with this Query subclass to retrieve the scope
|
||||
|
|
@ -66,14 +68,15 @@ namespace session {
|
|||
* defined to be non-copyable)
|
||||
*/
|
||||
template<class MO>
|
||||
class ContentsQuery
|
||||
class ScopeQuery
|
||||
: public Query<Placement<MO> >
|
||||
, public Query<Placement<MO> >::iterator
|
||||
{
|
||||
typedef Query<Placement<MO> > _Query;
|
||||
|
||||
QueryResolver const& index_;
|
||||
PlacementMO const& container_;
|
||||
QueryResolver const& index_;
|
||||
PlacementMO const& startPoint_;
|
||||
Literal what_to_discover_;
|
||||
|
||||
|
||||
typedef typename _Query::iterator _QIter;
|
||||
|
|
@ -85,12 +88,14 @@ namespace session {
|
|||
typedef function<bool(Val)> ContentFilter;
|
||||
|
||||
|
||||
ContentsQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope)
|
||||
ScopeQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope,
|
||||
Literal direction)
|
||||
: _Query (_Query::defineQueryTypeID (Goal::DISCOVERY))
|
||||
, _QIter ()
|
||||
, index_(resolver)
|
||||
, container_(scope)
|
||||
, startPoint_(scope)
|
||||
, what_to_discover_(direction)
|
||||
{
|
||||
resetResultIteration (_Query::resolveBy(index_));
|
||||
}
|
||||
|
|
@ -106,7 +111,13 @@ namespace session {
|
|||
PlacementMO const&
|
||||
searchScope () const
|
||||
{
|
||||
return container_;
|
||||
return startPoint_;
|
||||
}
|
||||
|
||||
Literal
|
||||
searchDirection () const
|
||||
{
|
||||
return what_to_discover_;
|
||||
}
|
||||
|
||||
ContentFilter
|
||||
|
|
@ -138,5 +149,29 @@ namespace session {
|
|||
};
|
||||
|
||||
|
||||
template<class MO>
|
||||
struct ContentsQuery
|
||||
: ScopeQuery<MO>
|
||||
{
|
||||
ContentsQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope)
|
||||
: ScopeQuery<MO> (resolver,scope, "content")
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<class MO>
|
||||
struct PathQuery
|
||||
: ScopeQuery<MO>
|
||||
{
|
||||
PathQuery (QueryResolver const& resolver,
|
||||
PlacementMO const& scope)
|
||||
: ScopeQuery<MO> (resolver,scope, "parents")
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
|
||||
}} // namespace mobject::session
|
||||
#endif
|
||||
|
|
@ -115,7 +115,7 @@ namespace session {
|
|||
scoped_ptr<SessionImpl> tmpS (new SessionImpl (*tmpD));
|
||||
|
||||
TODO ("reset the assets registered with AssetManager");
|
||||
// Ichthyo-intern: ticket #95
|
||||
/////////////////////////////////////////////////////////////////// TICKET #154
|
||||
|
||||
TODO ("thread lock");
|
||||
pDefs_.swap (tmpD);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ PLANNED "AddClip_test" AddClip_test <<END
|
|||
END
|
||||
|
||||
|
||||
PLANNED "discovering contents" ContentsQuery_test <<END
|
||||
PLANNED "discovering scopes" ScopeQuery_test <<END
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
PlacementIndexQuery(Test) - querying the placement index through the generic query interface
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "proc/mobject/session/query-resolver.hpp"
|
||||
#include "proc/mobject/session/scope-query.hpp"
|
||||
#include "proc/mobject/session/placement-index-query-resolver.hpp"
|
||||
#include "proc/mobject/session/test-scopes.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
namespace test {
|
||||
|
||||
using PathQuery;
|
||||
using ContentsQuery;
|
||||
using util::isSameObject;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* @test accessing the PlacementIndex through the generic query interface,
|
||||
* for discovering scope contents and containing scope.
|
||||
*
|
||||
* @see mobject::session::PlacementIndex
|
||||
* @see mobject::session::QueryResolver
|
||||
* @see mobject::session::ContentsQuery
|
||||
*/
|
||||
class PlacementIndexQuery_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
checkQueryResolverWrapper();
|
||||
checkQueryOperations();
|
||||
}
|
||||
|
||||
void
|
||||
checkQueryResolverWrapper()
|
||||
{
|
||||
PPIdx index = build_testScopes();
|
||||
QueryResolver const& resolver1 (*index);
|
||||
QueryResolver const& resolver2 (*index);
|
||||
|
||||
ASSERT (isSameObject (resolver1, resolver2));
|
||||
index = build_testScopes();
|
||||
}
|
||||
|
||||
void
|
||||
checkQueryOperations()
|
||||
{
|
||||
// Prepare an (test)Index (dummy "session")
|
||||
PPIdx index = build_testScopes();
|
||||
PlacementIndexQueryResolver resolver(index);
|
||||
|
||||
discover (ContentsQuery<MObject> (resolver));
|
||||
|
||||
PlacementMO& elm = *ContentsQuery<TestSubMO21>(resolver);
|
||||
|
||||
discover (PathQuery(resolver,elm));
|
||||
}
|
||||
|
||||
|
||||
template<class IT>
|
||||
void
|
||||
discover (IT result)
|
||||
{
|
||||
for ( ; result; ++result)
|
||||
cout << string(*result) << endl;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (PlacementIndexQuery_test, "unit session");
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "proc/mobject/session/query-resolver.hpp"
|
||||
#include "proc/mobject/session/contents-query.hpp"
|
||||
#include "proc/mobject/session/scope-query.hpp"
|
||||
#include "proc/mobject/session/test-scopes.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -36,49 +36,55 @@ namespace mobject {
|
|||
namespace session {
|
||||
namespace test {
|
||||
|
||||
using session::ContentsQuery;
|
||||
using ContentsQuery;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* @test how to discover the contents of a container-like part of the high-level model.
|
||||
* As this container-like object is just a concept and actually implemented
|
||||
* by the PlacementIndex, this includes enumerating a scope. The discovered
|
||||
* contents will be filtered by a runtime type check.
|
||||
/**********************************************************************************************
|
||||
* @test how to discover contents or location of a container-like part of the high-level model.
|
||||
* As this container-like object is just a concept and actually implemented by the
|
||||
* PlacementIndex, this means querying the index for elements registered with
|
||||
* a given scope or finding the enclosing scopes. The discovered
|
||||
* elements will be filtered by a runtime type check.
|
||||
*
|
||||
* @todo cover using an additional dynamic filter on the results
|
||||
*
|
||||
* @see mobject::PlacementIndex
|
||||
* @see mobject::session::PlacementIndex
|
||||
* @see mobject::session::QueryResolver
|
||||
* @see mobject::session::ContentsQuery
|
||||
*/
|
||||
class ContentsQuery_test : public Test
|
||||
class ScopeQuery_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
|
||||
// Prepare an (test)Index backing the PlacementRefs
|
||||
// Prepare an (test)Index (dummy "session")
|
||||
PPIdx index = build_testScopes();
|
||||
PlacementMO scope (index->getRoot());
|
||||
PlacementMO& scope (index->getRoot());
|
||||
QueryResolver const& resolver (*index);
|
||||
|
||||
discover (ContentsQuery<MObject> (resolver,scope));
|
||||
discover (ContentsQuery<DummyMO> (resolver,scope));
|
||||
discover (ContentsQuery<TestSubMO1> (resolver,scope));
|
||||
discover (ContentsQuery<TestSubMO2> (resolver,scope));
|
||||
discover (ContentsQuery<TestSubMO21>(resolver,scope));
|
||||
discover (ScopeQuery<MObject> (resolver,scope, "contents"));
|
||||
discover (ScopeQuery<DummyMO> (resolver,scope, "contents"));
|
||||
discover (ScopeQuery<TestSubMO1> (resolver,scope, "contents"));
|
||||
discover (ScopeQuery<TestSubMO2> (resolver,scope, "contents"));
|
||||
|
||||
ScopeQuery<TestSubMO21> specialEl(resolver,scope, "contents");
|
||||
|
||||
discover (specialEl);
|
||||
discover (ScopeQuery<MObject> (resolver,specialEL, "parents"));
|
||||
discover (ScopeQuery<MObject> (resolver,specialEL, "path"));
|
||||
discover (ScopeQuery<TestSubMO2> (resolver,specialEL, "path"));
|
||||
}
|
||||
|
||||
|
||||
template<class MO>
|
||||
void
|
||||
discover (ContentsQuery<MO> const& query)
|
||||
discover (ScopeQuery<MO> const& query)
|
||||
{
|
||||
typedef typename ContentsQuery<MO>::iterator I;
|
||||
typedef typename ScopeQuery<MO>::iterator I;
|
||||
|
||||
for (I elm(query);
|
||||
elm; ++elm)
|
||||
|
|
@ -89,7 +95,7 @@ namespace test {
|
|||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (ContentsQuery_test, "unit session");
|
||||
LAUNCHER (ScopeQuery_test, "unit session");
|
||||
|
||||
|
||||
}}} // namespace mobject::session::test
|
||||
Loading…
Reference in a new issue