From c3441ac26a6d1de7d383e7f98f3507f16b89c1eb Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 24 Oct 2009 00:23:22 +0200 Subject: [PATCH] WIP Query implementation draft... --- src/lib/multifact.hpp | 2 +- src/proc/mobject/session/query-resolver.cpp | 53 +++++++ src/proc/mobject/session/query-resolver.hpp | 139 ++++++++++++++---- .../mobject/session/query-resolver-test.cpp | 10 +- 4 files changed, 171 insertions(+), 33 deletions(-) create mode 100644 src/proc/mobject/session/query-resolver.cpp diff --git a/src/lib/multifact.hpp b/src/lib/multifact.hpp index 557e52375..1e15949eb 100644 --- a/src/lib/multifact.hpp +++ b/src/lib/multifact.hpp @@ -146,7 +146,7 @@ namespace lib { /** * Convenience shortcut for automatically setting up * a production line, fabricating a singleton instance - * of the given target type (TAR) + * of the given target type (IMP) */ template class Singleton diff --git a/src/proc/mobject/session/query-resolver.cpp b/src/proc/mobject/session/query-resolver.cpp new file mode 100644 index 000000000..990aed9fd --- /dev/null +++ b/src/proc/mobject/session/query-resolver.cpp @@ -0,0 +1,53 @@ +/* + QueryResolver - interface for discovering contents of a scope + + 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. + +* *****************************************************/ + + +#include "proc/mobject/session/query-resolver.hpp" +//#include "proc/mobject/session/track.hpp" +//#include "proc/mobject/placement.hpp" +//#include "proc/mobject/session/mobjectfactory.hpp" +//#include "proc/asset/track.hpp" + +namespace mobject { +namespace session { + + + + QueryResolver::~QueryResolver() { } + + + + /** TODO??? */ + void + QueryResolver::issue (Goal& query) + { + if (!canHandleQuery (query.getQID())) + throw lumiera::error::Invalid ("unable to resolve this kind of query"); ////TICKET #197 + + UNIMPLEMENTED ("dispatch-mechanism for re-discovering specific type-context"); + + } + + + + +}} // namespace mobject::session diff --git a/src/proc/mobject/session/query-resolver.hpp b/src/proc/mobject/session/query-resolver.hpp index dc0bd6960..6179f6018 100644 --- a/src/proc/mobject/session/query-resolver.hpp +++ b/src/proc/mobject/session/query-resolver.hpp @@ -26,7 +26,9 @@ //#include "proc/mobject/mobject.hpp" //#include "proc/mobject/placement.hpp" +#include "lib/typed-counter.hpp" #include "lib/iter-adapter.hpp" +#include "lib/util.hpp" //#include //#include @@ -37,37 +39,104 @@ namespace mobject { namespace session { - class Scope; + using util::unConst; + + +// class Scope; + class QueryResolver; + /** * TODO type comment + * Query ABC */ - template ///////////////////////TODO: can we get rid of that type parameter? in conjunction with the virtual functions, it causes template code bloat - class Query + class Goal { public: - virtual ~Query() {} + virtual ~Goal() {} - /* results retrieval */ + enum Kind + { GENERIC = 0 + , DISCOVERY + }; - typedef MO* Cur; - typedef lib::IterAdapter iterator; + struct QueryID + { + Kind kind; + size_t type; + }; - iterator operator()(){ return this->runQuery(); } + QueryID getQID() { return id_; } - static bool hasNext (const Query* thisQuery, Cur& pos) { return thisQuery->isValid(pos); } - static void iterNext (const Query* thisQuery, Cur& pos) { pos = thisQuery->nextResult(); } - /* diagnostics */ - static size_t query_cnt(); + class Result + { + void *cur_; + + protected: + template + RES& access() + { + REQUIRE (cur_); + return *reinterpret_cast (cur_); + } + }; + static bool hasNext (const Goal* thisQuery, Result& pos) { return unConst(thisQuery)->isValid(pos); } ////TICKET #375 + static void iterNext (const Goal* thisQuery, Result& pos) { return unConst(thisQuery)->nextResult(pos);} protected: - virtual iterator runQuery() =0; - + QueryID id_; + + Goal (QueryID qid) + : id_(quid) + { } + /* iteration control */ - virtual bool isValid (Cur& pos) const =0; - virtual Cur const& nextResult() const =0; + virtual bool isValid (Result& pos) =0; /////TODO danger of template bloat? + virtual Result const& nextResult(Result& pos) =0; + }; + + + + /** Context used for generating type-IDs to denote + * the specific result types of issued queries */ + typedef lib::TypedContext ResultType; + + + /** + * TODO type comment + * Concrete query to yield specifically typed result elements + */ + template + class Query + : public Goal + { + static QueryID + defineQueryTypeID () + { + QueryID id = {Goal::GENERIC, ResultType::ID::get()}; + return id; + } + + public: + Query() + : Goal (defineQueryTypeID()) + { } + + /* results retrieval */ + class Cursor : public Goal::Result + { + public: + RES& operator* () { return access(); } + RES* operator->() { return & access(); } + }; + + typedef lib::IterAdapter iterator; + + operator iterator() ; + iterator operator() (QueryResolver const& resolver); + }; @@ -79,26 +148,42 @@ namespace session { public: - virtual ~QueryResolver() {} + virtual ~QueryResolver() ; /** issue a query to retrieve contents - * @param scope or container on which to discover contents - * @return an iterator to yield all elements of suitable type - * - * @todo doesn't this create a circular dependency? scope indirectly relies on QueryResolver, right?? + * The query is handed over internally to a suitable resolver implementation. + * After returning, results can be obtained from the query by iteration. + * @throw lumiera::Error subclass if query evaluation flounders. + * This might be broken logic, invalid input, misconfiguration + * or failure of an external facility used for resolution. + * @note a query may yield no results, in which case the iterator is empty. */ - template - typename Query::iterator - query (Scope const& scope) - { - UNIMPLEMENTED ("create a specific contents query to enumerate contents of scope"); - } + void issue (Goal& query); + protected: + virtual bool canHandleQuery (Goal::QueryID qID) const =0; + }; ///////////////////////////TODO currently just fleshing the API + template + inline typename Query::iterator + Query::operator() (QueryResolver const& resolver) + { + resolver.issue (*this); + return *this; + } + + + template + Query::operator iterator() + { + UNIMPLEMENTED ("how to get the result iterator"); + } + + }} // namespace mobject::session #endif diff --git a/tests/components/proc/mobject/session/query-resolver-test.cpp b/tests/components/proc/mobject/session/query-resolver-test.cpp index e78894b2d..389926ba5 100644 --- a/tests/components/proc/mobject/session/query-resolver-test.cpp +++ b/tests/components/proc/mobject/session/query-resolver-test.cpp @@ -84,12 +84,12 @@ namespace test { { QueryResolver& resolver = buildTestQueryResolver(); Query firstQuery; - Query::iterator ii = resolver.issue (firstQuery); - explore (ii); + resolver.issue (firstQuery); + explore (firstQuery); - Query secondtQuery; - Query::iterator iii = resolver.issue (secondQuery); - explore (iii); + Query secondQuery; + resolver.issue (secondQuery); + explore (secondQuery); } template