diff --git a/src/proc/mobject/session/placement-index-query-resolver.hpp b/src/proc/mobject/session/placement-index-query-resolver.hpp new file mode 100644 index 000000000..4ad794227 --- /dev/null +++ b/src/proc/mobject/session/placement-index-query-resolver.hpp @@ -0,0 +1,212 @@ +/* + PLACEMENT-INDEX.hpp - tracking individual Placements and their relations + + Copyright (C) Lumiera.org + 2009, Hermann Vosseler + + 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 +#include +#include +#include + + +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 pTab_; + + public: + typedef Placement PlacementMO; + typedef PlacementRef PRef; + typedef PlacementMO::ID const& ID; + + typedef session::Goal::QueryID const& QID; + + + PlacementMO& find (ID) const; + + template + Placement& find (PlacementMO::Id) const; + template + Placement& find (PlacementRef const&) const; + + PlacementMO& getScope (PlacementMO const&) const; + PlacementMO& getScope (ID) const; + + vector 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 + typename session::Query >::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 Factory; + + static Factory create; + + ~PlacementIndex(); + + void clear(); + + protected: + PlacementIndex() ; + + friend class lib::factory::Factory > >; + }; + ////////////////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 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 & + fetch_PlacementIndex(Placement::ID const&) ; + + + + + /* === forwarding implementations of the templated API === */ + + template + inline Placement& + PlacementIndex::find (PlacementMO::Id id) const + { + PlacementMO& result (find (id)); + REQUIRE (INSTANCEOF (MO, &result) ); + return static_cast&> (result); + } + + + template + inline Placement& + PlacementIndex::find (PlacementRef const& pRef) const + { + PlacementMO::Id 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 + inline typename session::Query >::iterator + PlacementIndex::query (PlacementMO& scope) const + { + UNIMPLEMENTED ("actually run the containment query"); + } + + inline Placement& + 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 diff --git a/src/proc/mobject/session/scope-locator.hpp b/src/proc/mobject/session/scope-locator.hpp index d75bdf980..67bbd2fad 100644 --- a/src/proc/mobject/session/scope-locator.hpp +++ b/src/proc/mobject/session/scope-locator.hpp @@ -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" diff --git a/src/proc/mobject/session/contents-query.hpp b/src/proc/mobject/session/scope-query.hpp similarity index 78% rename from src/proc/mobject/session/contents-query.hpp rename to src/proc/mobject/session/scope-query.hpp index 07373b79c..5c9880f95 100644 --- a/src/proc/mobject/session/contents-query.hpp +++ b/src/proc/mobject/session/scope-query.hpp @@ -27,6 +27,7 @@ #include "proc/mobject/placement.hpp" #include "proc/mobject/session/query-resolver.hpp" +#include "lib/symbol.hpp" #include @@ -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 ContentsQuery + class ScopeQuery : public Query > , public Query >::iterator { typedef Query > _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 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 + struct ContentsQuery + : ScopeQuery + { + ContentsQuery (QueryResolver const& resolver, + PlacementMO const& scope) + : ScopeQuery (resolver,scope, "content") + { } + + }; + + + template + struct PathQuery + : ScopeQuery + { + PathQuery (QueryResolver const& resolver, + PlacementMO const& scope) + : ScopeQuery (resolver,scope, "parents") + { } + + }; + + }} // namespace mobject::session #endif diff --git a/src/proc/mobject/session/sess-manager-impl.cpp b/src/proc/mobject/session/sess-manager-impl.cpp index 4428e587d..5d7d94e62 100644 --- a/src/proc/mobject/session/sess-manager-impl.cpp +++ b/src/proc/mobject/session/sess-manager-impl.cpp @@ -115,7 +115,7 @@ namespace session { scoped_ptr tmpS (new SessionImpl (*tmpD)); TODO ("reset the assets registered with AssetManager"); - // Ichthyo-intern: ticket #95 + /////////////////////////////////////////////////////////////////// TICKET #154 TODO ("thread lock"); pDefs_.swap (tmpD); diff --git a/tests/43session.tests b/tests/43session.tests index 7320329bc..f310e2d1d 100644 --- a/tests/43session.tests +++ b/tests/43session.tests @@ -6,7 +6,7 @@ PLANNED "AddClip_test" AddClip_test < + + 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 +#include + + + +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 (resolver)); + + PlacementMO& elm = *ContentsQuery(resolver); + + discover (PathQuery(resolver,elm)); + } + + + template + void + discover (IT result) + { + for ( ; result; ++result) + cout << string(*result) << endl; + } + + }; + + + /** Register this test class... */ + LAUNCHER (PlacementIndexQuery_test, "unit session"); + + +}}} // namespace mobject::session::test diff --git a/tests/components/proc/mobject/session/contents-query-test.cpp b/tests/components/proc/mobject/session/scope-query-test.cpp similarity index 59% rename from tests/components/proc/mobject/session/contents-query-test.cpp rename to tests/components/proc/mobject/session/scope-query-test.cpp index 3b200d07c..8ec2c9d49 100644 --- a/tests/components/proc/mobject/session/contents-query-test.cpp +++ b/tests/components/proc/mobject/session/scope-query-test.cpp @@ -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 (resolver,scope)); - discover (ContentsQuery (resolver,scope)); - discover (ContentsQuery (resolver,scope)); - discover (ContentsQuery (resolver,scope)); - discover (ContentsQuery(resolver,scope)); + discover (ScopeQuery (resolver,scope, "contents")); + discover (ScopeQuery (resolver,scope, "contents")); + discover (ScopeQuery (resolver,scope, "contents")); + discover (ScopeQuery (resolver,scope, "contents")); + + ScopeQuery specialEl(resolver,scope, "contents"); + + discover (specialEl); + discover (ScopeQuery (resolver,specialEL, "parents")); + discover (ScopeQuery (resolver,specialEL, "path")); + discover (ScopeQuery (resolver,specialEL, "path")); } template void - discover (ContentsQuery const& query) + discover (ScopeQuery const& query) { - typedef typename ContentsQuery::iterator I; + typedef typename ScopeQuery::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