implemented the mechanism for dispatch-to-concrete resolution

This commit is contained in:
Fischlurch 2009-10-30 18:37:08 +01:00
parent 572f26edc8
commit f70f8c4e4a
5 changed files with 96 additions and 27 deletions

View file

@ -62,7 +62,7 @@ namespace mobject { ///////////////////////////////////////////TODO: shouldn't t
*/
class PlacementIndex
: public session::QueryResolver ////////TODO: really inherit here?
, boost::noncopyable
// , boost::noncopyable ////////TODO : where to put the "noncopyable" base
{
class Table;

View file

@ -22,45 +22,91 @@
#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"
#include "lib/multifact-arg.hpp"
namespace mobject {
namespace session {
using lib::factory::MultiFact;
using lib::factory::BuildRefcountPtr;
/* generate vtables here */
/* generate vtables here... */
Goal::~Goal() { }
QueryResolver::~QueryResolver() { }
Resolution::~Resolution() { }
QueryResolver::~QueryResolver() { }
typedef Goal::QueryID const& QID;
/** we're going to use QueryID as Map key... */
inline bool
operator< (QID q1, QID q2)
{
return (q1.kind < q2.kind)
|| (q1.kind == q2.kind
&& q1.type < q2.type
);
}
/* == dispatch to resolve typed queries == */
/** factory used as dispatcher table
* for resolving typed queries */
typedef MultiFact< Resolution(Goal&) // nominal signature of fabrication
, Goal::QueryID // select resolution function by kind-of-Query
, BuildRefcountPtr // wrapper: manage result set by smart-ptr
> DispatcherTable; //
struct QueryDispatcher
: DispatcherTable
{
PReso
handle (Goal& query)
{
QID qID = query.getQID();
ENSURE (contains (qID));
return (*this) (qID, query);
} //qID picks the resolution function
};
QueryResolver::QueryResolver ()
: dispatcher_(new QueryDispatcher)
{ }
/** TODO??? */
/** @par implementation
* For actually building a result set, the QueryResolver base implementation
* uses an embedded dispatcher table. The concrete query resolving facilities,
* when implementing the QueryResolver interface, are expected to register
* individual resolution functions into this QueryDispatcher table.
* Whenever issuing a Goal, a suitable resolution function is picked
* based on the Goal::QueryID, which contains an embedded type code.
* Thus, the individual resolution function can (re)establish a
* typed context and downcast the Goal appropriately
*/
PReso
QueryResolver::issue (Goal& query) const
{
TODO ("ensure proper initialisation");
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");
return dispatcher_->handle(query);
}

View file

@ -31,6 +31,7 @@
#include "lib/iter-adapter.hpp"
#include "lib/util.hpp"
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <tr1/memory>
//#include <vector>
@ -43,6 +44,7 @@ namespace mobject {
namespace session {
using util::unConst;
using boost::noncopyable;
class Goal;
@ -60,6 +62,7 @@ namespace session {
* Query ABC
*/
class Goal
: noncopyable
{
public:
virtual ~Goal() ;
@ -78,6 +81,12 @@ namespace session {
QueryID getQID() { return id_; }
/**
* Single Solution, possibly part of a result set.
* A pointer-like object, usually to be down-casted
* to a specifically typed Query::Cursor
* @see Resolution
*/
class Result
: public lib::BoolCheckable<Result>
{
@ -117,6 +126,15 @@ namespace session {
* the specific result types of issued queries */
typedef lib::TypedContext<Goal::Result> ResultType;
template<typename RES>
inline size_t
getResultTypeID() ///< @return unique ID denoting result type RES
{
return ResultType::ID<RES>::get();
}
/**
* TODO type comment
@ -129,7 +147,7 @@ namespace session {
static QueryID
defineQueryTypeID ()
{
QueryID id = {Goal::GENERIC, ResultType::ID<RES>::get()};
QueryID id = {Goal::GENERIC, getResultTypeID<RES>() };
return id;
}
@ -138,6 +156,7 @@ namespace session {
: Goal (defineQueryTypeID())
{ }
/* results retrieval */
class Cursor
: public Goal::Result
@ -156,7 +175,8 @@ namespace session {
typedef lib::IterAdapter<Cursor,PReso> iterator;
iterator operator() (QueryResolver const& resolver);
iterator
operator() (QueryResolver const& resolver);
};
@ -166,6 +186,7 @@ namespace session {
* of an individual query resolution
*/
class Resolution
: noncopyable
{
public:
typedef Goal::Result Result;
@ -195,9 +216,11 @@ namespace session {
/**
* Interface: a facility for resolving (some) queries
* TODO type comment
*/
class QueryResolver
: noncopyable
{
boost::scoped_ptr<QueryDispatcher> dispatcher_;

View file

@ -54,23 +54,23 @@ namespace test {
template<typename TY>
class DummySolution;
class DummySolutions;
template<>
class DummySolution<int>
class DummySolutions<int>
{
int resNr_;
public:
DummySolution() : resNr_(7) {}
DummySolutions() : resNr_(7) {}
int* next () { --resNr_; return &resNr_; }
bool exhausted() { return bool(resNr_); }
};
template<>
class DummySolution<string>
: DummySolution<int>
class DummySolutions<string>
: DummySolutions<int>
{
string currentText_;
@ -79,7 +79,7 @@ namespace test {
next ()
{
static const char* lumi ="Lumiera";
currentText_ = string (lumi + *DummySolution<int>::next());
currentText_ = string (lumi + *DummySolutions<int>::next());
return &currentText_;
}
};
@ -88,7 +88,7 @@ namespace test {
struct DummyResultSet
: Resolution
{
DummySolution<TY> solution_;
DummySolutions<TY> solutions_;
typedef typename Query<TY>::Cursor Cursor;
@ -96,7 +96,7 @@ namespace test {
prepareResolution()
{
Cursor cursor;
cursor.pointAt (solution_.next());
cursor.pointAt (solutions_.next());
return cursor;
}
@ -105,10 +105,10 @@ namespace test {
{
Cursor& cursor = static_cast<Cursor&> (pos);
if (solution_.exhausted())
if (solutions_.exhausted())
cursor.point_at (0);
else
cursor.point_at (solution_.next());
cursor.point_at (solutions_.next());
}
};
@ -127,7 +127,7 @@ namespace test {
bool
wantResultType (Goal::QueryID qID) const
{
return qID.type == ResultType::ID<TY>::get();
return qID.type == getResultTypeID<TY>();
}
};

View file

@ -5562,9 +5562,9 @@ Using transitions is a very basic task and thus needs viable support by the GUI.
Because of this experience, ichthyo wants to support a more general case of transitions, which have N output connections, behave similar to their &quot;simple&quot; counterpart, but leave out the mixing step. As a plus, such transitions can be inserted at the source ports of N clips or between any intermediary or final output pipes as well. Any transition processor capable of handling this situation should provide some flag, in order to decide if he can be placed in such a manner. (wichin the builder, encountering a inconsistently placed transition is just an [[building error|BuildingError]])
</pre>
</div>
<div title="TypedQueryProblem" modifier="Ichthyostega" modified="200910231708" created="200910231618" tags="Rules dynamic" changecount="9">
<div title="TypedQueryProblem" modifier="Ichthyostega" modified="200910301629" created="200910231618" tags="Rules dynamic" changecount="10">
<pre>//the problem of processing specifically typed queries without tying query and QueryResolver.//&lt;br/&gt;This problem can be seen as a instance of the problematic situation encountered with most visitation schemes: we want entities and tools (visitors) to work together, without being forced to commit to a pre-defined table of operations. In the situation at hand here, we want //some entities// &amp;mdash; which we don't know &amp;mdash; to issue //some queries// &amp;mdash; which we don't know either. Obviously, such a problem can be solved only by controlling the scope of this incomplete knowledge, and the sequence in time of building it.
Thus, to re-state the problem more specifically, we want the //definition//&amp;nbsp; of the entities to be completely separate of those concerning the details of the query resolution mechanism, so to be able to design, reason, verify and extend each one without being forced into concern about the details of the respective other side. So, the buildup of the combined structure has to be postponed &amp;mdash; assuring it //has//&amp;nbsp; happened at the point it's operations are required.
Thus, to re-state the problem more specifically, we want the //definition//&amp;nbsp; of the entities to be completely separate of those definitions concerning the details of the query resolution mechanism, so to be able to design, reason, verify and extend each one without being forced into concern about the details of the respective other side. So, the buildup of the combined structure has to be postponed &amp;mdash; assuring it //has//&amp;nbsp; happened at the point it's operations are required.
!Solution Stages
* in ''static scope'' (while compiling), just a {{{Query&lt;TY&gt;}}} gets mentioned.&lt;br/&gt;As this is the only chance for driving a specifically typed context, we need to prepare a registration mechanism, to allow for //remembering//&amp;nbsp; this context later.