2010-11-08 04:48:50 +01:00
|
|
|
/*
|
|
|
|
|
OUTPUT-MAPPING.hpp - generic interface for translation of output designations
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2010, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
2010-12-17 23:28:49 +01:00
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
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.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
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.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
/** @file output-mapping.hpp
|
|
|
|
|
** Translating and wiring output designations.
|
|
|
|
|
** OutputMapping is a complement to the OutputDesignation handles
|
|
|
|
|
** used at various places in the high-level model. It is used when
|
|
|
|
|
** translating a given output spec into another connection target
|
2012-01-27 00:14:21 +01:00
|
|
|
** - when connecting a model port to a concrete external output
|
2010-11-28 01:43:55 +01:00
|
|
|
** - when connecting a timeline to a viewer element
|
2012-01-27 00:14:21 +01:00
|
|
|
** - for implementing the viewer input selection "switchboard"
|
2010-11-28 01:43:55 +01:00
|
|
|
** - for translating output designation of virtual clips
|
|
|
|
|
** OutputMapping is to be used as value object, holding concrete
|
|
|
|
|
** connections and wiring. For each of the mentioned usage situations,
|
|
|
|
|
** it needs to be adapted specifically, which is achieved by template
|
|
|
|
|
** (generic) programming: The usage situation provides a definition
|
|
|
|
|
** context DEF to fill in the variable parts of the implementation.
|
|
|
|
|
** This definition context is actually instantiated (as base class).
|
|
|
|
|
** The mapping table actually just stores an association of hash
|
|
|
|
|
** values, which typically are interpreted as asset::ID<Pipe>.
|
2012-01-27 00:14:21 +01:00
|
|
|
** But the actual mapping result is retrieved on each access
|
2010-11-28 01:43:55 +01:00
|
|
|
** by invoking a functor on the stored hash value,
|
|
|
|
|
** thus the final resolution is done \em late.
|
|
|
|
|
**
|
|
|
|
|
** @see OutputDesignation
|
|
|
|
|
** @see OutputMapping_test
|
|
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
#ifndef PROC_MOBJECT_OUTPUT_MAPPING_H
|
|
|
|
|
#define PROC_MOBJECT_OUTPUT_MAPPING_H
|
|
|
|
|
|
2010-11-28 05:18:57 +01:00
|
|
|
#include "proc/asset/pipe.hpp"
|
2010-11-27 03:59:07 +01:00
|
|
|
#include "lib/bool-checkable.hpp"
|
2010-11-28 05:18:57 +01:00
|
|
|
#include "lib/error.hpp"
|
2010-11-25 05:35:50 +01:00
|
|
|
#include "lib/query.hpp"
|
2010-11-27 06:01:31 +01:00
|
|
|
#include "lib/util.hpp"
|
2010-11-24 06:21:32 +01:00
|
|
|
|
2010-11-27 04:21:39 +01:00
|
|
|
#include <boost/operators.hpp>
|
2010-11-27 06:01:31 +01:00
|
|
|
#include <map>
|
2010-11-27 03:59:07 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
|
|
|
|
|
|
2011-12-02 16:10:03 +01:00
|
|
|
namespace proc {
|
2010-11-08 04:48:50 +01:00
|
|
|
namespace mobject {
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-24 06:21:32 +01:00
|
|
|
namespace { // Helper to extract and rebind definition types
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
/**
|
|
|
|
|
* @internal used by OutputMapping
|
|
|
|
|
* to figure out the mapping target type
|
|
|
|
|
*/
|
2010-11-24 06:21:32 +01:00
|
|
|
template<class DEF>
|
2010-11-25 04:52:49 +01:00
|
|
|
class _def
|
2010-11-24 06:21:32 +01:00
|
|
|
{
|
2010-11-25 04:52:49 +01:00
|
|
|
typedef asset::ID<asset::Pipe> PId;
|
2010-11-24 06:21:32 +01:00
|
|
|
|
|
|
|
|
template<typename FUN>
|
|
|
|
|
struct Rebind;
|
|
|
|
|
|
|
|
|
|
template<typename RET>
|
|
|
|
|
struct Rebind<RET(DEF::*)(PId)>
|
|
|
|
|
{
|
|
|
|
|
typedef RET Res;
|
|
|
|
|
};
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
typedef typeof(&DEF::output) OutputMappingMemberFunc; // GCC extension: "typeof"
|
2010-11-25 04:52:49 +01:00
|
|
|
typedef Rebind<OutputMappingMemberFunc> Rebinder;
|
2010-11-24 06:21:32 +01:00
|
|
|
|
2010-11-25 04:52:49 +01:00
|
|
|
public:
|
|
|
|
|
typedef typename Rebinder::Res Target;
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-24 06:21:32 +01:00
|
|
|
};
|
2010-11-28 01:43:55 +01:00
|
|
|
}//(End) type rebinding helper
|
2010-11-08 04:48:50 +01:00
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
namespace error = lumiera::error;
|
2012-11-26 01:22:01 +01:00
|
|
|
using lib::Query;
|
2010-11-27 06:01:31 +01:00
|
|
|
using asset::HashVal;
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
|
|
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
/**
|
|
|
|
|
* OutputMapping is a facility to resolve output designations.
|
2012-01-27 00:14:21 +01:00
|
|
|
* The session/model uses preliminary or partial output specifications,
|
|
|
|
|
* which are to be resolved to an actual system output while building
|
|
|
|
|
* and preparing a render network for operation (playback/rendering).
|
|
|
|
|
* For a given specification, resolution to the desired target spec
|
|
|
|
|
* may be derived by querying the OutputMapping. Here, the kind of
|
|
|
|
|
* the target specification is defined through the type parameter.
|
2010-11-08 04:48:50 +01:00
|
|
|
*
|
2010-11-27 06:01:31 +01:00
|
|
|
* \par definition of specific mapping behaviour
|
|
|
|
|
*
|
|
|
|
|
* This is an generic map-like container, acting as Interface to be used
|
|
|
|
|
* in the signature of API functions either providing or requiring a Mapping.
|
|
|
|
|
* For each distinct usage situation, an instantiation of this template should
|
|
|
|
|
* be created, providing a <i>definition context</i> as template parameter.
|
|
|
|
|
* Instances of this concrete mapping type may then be default constructed
|
|
|
|
|
* and copied freely. The definition context is supposed to provide
|
|
|
|
|
* - a functor \c DEF::output usable as function pipe-ID --> Target
|
|
|
|
|
* - the concrete output-functor also defines the concrete Target type,
|
|
|
|
|
* which will be returned when accessing the OutputMapping
|
2010-11-28 05:18:57 +01:00
|
|
|
* - a function \c DEF::buildQuery(sourcePipeID,seqNr) yielding a (defaults)
|
|
|
|
|
* query to be issued in case of accessing a non existent mapping
|
2010-11-08 04:48:50 +01:00
|
|
|
*/
|
2010-11-23 03:40:11 +01:00
|
|
|
template<class DEF>
|
2010-11-08 04:48:50 +01:00
|
|
|
class OutputMapping
|
2010-11-27 06:01:31 +01:00
|
|
|
: public DEF
|
2010-11-08 04:48:50 +01:00
|
|
|
{
|
2010-11-25 04:52:49 +01:00
|
|
|
typedef _def<DEF> Setup;
|
|
|
|
|
|
2010-11-25 05:35:50 +01:00
|
|
|
typedef asset::ID<asset::Pipe> PId;
|
|
|
|
|
typedef asset::PPipe PPipe;
|
|
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
/* == mapping table storage == */
|
|
|
|
|
std::map<HashVal,HashVal> table_;
|
|
|
|
|
|
2010-11-08 04:48:50 +01:00
|
|
|
public:
|
2010-11-28 01:43:55 +01:00
|
|
|
typedef typename Setup::Target Target;
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
// using default ctor and copy operations
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
size_t size() const { return table_.size(); }
|
|
|
|
|
bool empty() const { return 0 == size(); }
|
|
|
|
|
void clear() { table_.clear(); }
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @internal transient resolution wrapper to be exposed by map-style access.
|
|
|
|
|
* A Resolver instance represents an output mapping result, yet to be fully resolved.
|
|
|
|
|
* It is created on the stack by the OutputMapping container and internally wired
|
|
|
|
|
* back to the container and the actually stored value (pipe-ID-hash) in the table.
|
|
|
|
|
* Actually retrieving the result value by the client code triggers invocation
|
|
|
|
|
* of the specific resolution functor, embedded in the definition context DEF,
|
|
|
|
|
* which was given when instantiating the OutputMapping template.
|
2010-11-28 01:43:55 +01:00
|
|
|
* @note depends on the template parameter of the enclosing OutputMapping type!
|
2010-11-27 06:01:31 +01:00
|
|
|
*/
|
2010-11-25 05:35:50 +01:00
|
|
|
class Resolver
|
2010-11-28 01:43:55 +01:00
|
|
|
: public lib::BoolCheckable<Resolver // bool conversion to signal "unconnected"...
|
|
|
|
|
, boost::equality_comparable<Resolver, Target, // final mapping result can be compared to Target...
|
|
|
|
|
boost::equality_comparable<Resolver> // mapping values can be compared.
|
|
|
|
|
> > //
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
OutputMapping& thisMapping_;
|
|
|
|
|
HashVal& pID_;
|
|
|
|
|
|
|
|
|
|
Resolver (OutputMapping& container, HashVal& resultVal)
|
|
|
|
|
: thisMapping_(container)
|
|
|
|
|
, pID_(resultVal)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
friend class OutputMapping;
|
|
|
|
|
|
|
|
|
|
/* copy by clients prohibited */
|
|
|
|
|
Resolver& operator= (Resolver const&);
|
|
|
|
|
|
2010-11-27 03:59:07 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
Target
|
|
|
|
|
resolve() const
|
|
|
|
|
{
|
|
|
|
|
REQUIRE (pID_);
|
|
|
|
|
PId targetPipeID (pID_);
|
2010-11-28 01:43:55 +01:00
|
|
|
return thisMapping_.resolveTarget (targetPipeID);
|
2010-11-27 06:01:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2010-11-28 01:43:55 +01:00
|
|
|
/** explicitly define a new target ID for this individual mapping
|
|
|
|
|
* @note the actually returned result depends on what the configured
|
|
|
|
|
* \c DEF::output functor will yield when invoked on this ID
|
|
|
|
|
*/
|
2010-11-27 03:59:07 +01:00
|
|
|
void
|
|
|
|
|
operator= (PId newId2map)
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
pID_ = newId2map;
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
2010-11-27 03:59:07 +01:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
operator= (PPipe newPipe2map)
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
REQUIRE (newPipe2map);
|
|
|
|
|
pID_ = newPipe2map->getID();
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
void
|
|
|
|
|
disconnect() ///< switch this individual mapping into \em unconnected state
|
|
|
|
|
{
|
|
|
|
|
pID_ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** actually retrieve the target object of the mapping.
|
|
|
|
|
* This operation is invoked when client code accesses
|
|
|
|
|
* the result of an OutputMapping query.
|
|
|
|
|
* @return result of invoking the configured \c DEF::output functor
|
|
|
|
|
* @throw error::Logic when resoving an \em unconnected mapping
|
|
|
|
|
*/
|
2010-11-25 05:35:50 +01:00
|
|
|
operator Target()
|
|
|
|
|
{
|
2010-11-28 01:43:55 +01:00
|
|
|
if (!isValid())
|
|
|
|
|
throw error::Logic ("attempt to resolve an unconnected output mapping"
|
|
|
|
|
, error::LUMIERA_ERROR_UNCONNECTED);
|
2010-11-27 06:01:31 +01:00
|
|
|
return resolve();
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2010-11-28 01:43:55 +01:00
|
|
|
isValid() const ///< is this a valid \em connected mapping?
|
2010-11-25 05:35:50 +01:00
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return bool(pID_);
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-11-27 04:21:39 +01:00
|
|
|
/* === equality comparisons (boost::operators) === */
|
|
|
|
|
|
|
|
|
|
friend bool
|
|
|
|
|
operator== (Resolver const& a, Resolver const& b)
|
|
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return a.pID_ == b.pID_;
|
2010-11-28 05:18:57 +01:00
|
|
|
} // note: Resolver depends on template parameter DEF
|
2010-11-27 06:01:31 +01:00
|
|
|
// All instances of DEF are considered equivalent!
|
2010-11-27 04:21:39 +01:00
|
|
|
friend bool
|
|
|
|
|
operator== (Resolver const& rr, Target const& tval)
|
|
|
|
|
{
|
2010-11-27 06:01:31 +01:00
|
|
|
return rr.resolve() == tval;
|
2010-11-27 04:21:39 +01:00
|
|
|
}
|
2010-11-25 05:35:50 +01:00
|
|
|
};
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* === Map-style access for clients === */
|
|
|
|
|
|
2010-11-28 02:16:39 +01:00
|
|
|
Resolver operator[] (PId sourcePipeID);
|
|
|
|
|
Resolver operator[] (PPipe const& pipe);
|
2010-11-28 05:18:57 +01:00
|
|
|
Resolver operator[] (Query<asset::Pipe> query4pipe);
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
contains (PId mapping4sourcePipeID)
|
|
|
|
|
{
|
|
|
|
|
return util::contains (table_, mapping4sourcePipeID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
contains (PPipe sourcePipe)
|
|
|
|
|
{
|
|
|
|
|
return !sourcePipe
|
|
|
|
|
|| this->contains (sourcePipe->getID());
|
|
|
|
|
}
|
2010-11-28 01:43:55 +01:00
|
|
|
|
2010-11-27 06:01:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Target
|
2010-11-28 01:43:55 +01:00
|
|
|
resolveTarget (PId mappedPipeID)
|
2010-11-27 06:01:31 +01:00
|
|
|
{
|
2010-11-28 01:43:55 +01:00
|
|
|
return DEF::output (mappedPipeID);
|
2010-11-27 06:01:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Resolver
|
|
|
|
|
buildResolutionWrapper (HashVal tableSlot)
|
|
|
|
|
{
|
2010-11-28 05:18:57 +01:00
|
|
|
ASSERT (this->contains (tableSlot));
|
2010-11-27 06:01:31 +01:00
|
|
|
return Resolver (*this, table_[tableSlot]);
|
2010-11-25 05:35:50 +01:00
|
|
|
}
|
2010-11-08 04:48:50 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2010-11-28 02:16:39 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ===== Implementation details ===== */
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
namespace _mapping {
|
|
|
|
|
|
|
|
|
|
/** yield a suitable table slot for this query */
|
|
|
|
|
HashVal slot (Query<asset::Pipe> const&);
|
|
|
|
|
|
|
|
|
|
/** delegate target pipe resolution to the rules system */
|
|
|
|
|
HashVal resolveQuery (Query<asset::Pipe> const&);
|
2010-11-28 05:18:57 +01:00
|
|
|
|
|
|
|
|
/** detect the special case, when actually the Nth
|
|
|
|
|
* solution of a defaults query is requested */
|
|
|
|
|
uint is_defaults_query_with_channel (Query<asset::Pipe> const&);
|
|
|
|
|
|
|
|
|
|
/** ..and build the corresponding defaults source query for this case */
|
|
|
|
|
Query<asset::Pipe> build_corresponding_sourceQuery (Query<asset::Pipe> const&);
|
2010-11-28 01:43:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-11-28 05:18:57 +01:00
|
|
|
/** standard map-style access to an OutputMapping.
|
|
|
|
|
* For the given source pipe-ID the mapped target pipe-ID is fetched
|
|
|
|
|
* and then handed over to the configured \c DEF::output functor, which
|
|
|
|
|
* is assumed to calculate or retrieve the actual result object.
|
|
|
|
|
*
|
|
|
|
|
* \par default mappings
|
|
|
|
|
* whenever accessing an yet non-existent mapping, a query is issued
|
|
|
|
|
* behind the scenes to establish a suitable default mapping. The actual
|
|
|
|
|
* query is built from a query template by the \c DEF::buildQuery function
|
|
|
|
|
* and thus can be configured for the concrete usage situation of the mapping.
|
|
|
|
|
* @warning depending on the actually configured defaults query, there might be
|
|
|
|
|
* no solution, in which case an \em unconnected marker is retrieved and
|
|
|
|
|
* stored. Thus the yielded Resolver should be checked, if in doubt.
|
|
|
|
|
*/
|
2010-11-28 02:16:39 +01:00
|
|
|
template<class DEF>
|
|
|
|
|
inline typename OutputMapping<DEF>::Resolver
|
|
|
|
|
OutputMapping<DEF>::operator[] (PId sourcePipeID)
|
|
|
|
|
{
|
2010-11-28 05:18:57 +01:00
|
|
|
if (!contains (sourcePipeID))
|
2010-11-28 02:16:39 +01:00
|
|
|
{
|
|
|
|
|
// issue a defaults query to resolve this mapping first
|
|
|
|
|
Query<asset::Pipe> query4pipe = DEF::buildQuery (sourcePipeID);
|
|
|
|
|
table_[sourcePipeID] = _mapping::resolveQuery (query4pipe);
|
|
|
|
|
}
|
|
|
|
|
return buildResolutionWrapper (sourcePipeID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-11-28 05:18:57 +01:00
|
|
|
/** similar to the standard map-style access, but accepts
|
|
|
|
|
* a source pipe object instead of just a pipe-ID */
|
2010-11-28 02:16:39 +01:00
|
|
|
template<class DEF>
|
|
|
|
|
inline typename OutputMapping<DEF>::Resolver
|
|
|
|
|
OutputMapping<DEF>::operator[] (PPipe const& pipe)
|
|
|
|
|
{
|
|
|
|
|
REQUIRE (pipe);
|
|
|
|
|
return (*this) [pipe->getID()];
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-28 01:43:55 +01:00
|
|
|
|
|
|
|
|
/** determine an OutputMapping by resolving a complex query,
|
|
|
|
|
* instead of just picking a mapped pipe (which is the default usage).
|
|
|
|
|
* Accessing the OutputMapping this way by query enables all kinds of
|
|
|
|
|
* extended usages: It suffices that the given query somehow yields a Pipe,
|
|
|
|
|
* which then is considered the mapped result and handed over to the \c DEF::output
|
2010-11-28 05:18:57 +01:00
|
|
|
* functor for resolution to a result object to be returned.
|
|
|
|
|
*
|
|
|
|
|
* \par Query for the Nth default instance
|
|
|
|
|
* OutputMapping provides a special behaviour for retrieving "the Nth default pipe".
|
|
|
|
|
* The rationale being the request for connection to the Nth bus of a given kind, like
|
|
|
|
|
* e.g. the 3rd audio subgroup or the 2nd video master. This special behaviour is triggered
|
|
|
|
|
* by the predicate "ord(##)" in the query. The \em remainder of the query is supposed to
|
|
|
|
|
* designate a \em default in this case, rather then querying directly for the result of
|
|
|
|
|
* the mapping. Thus this remainder of the query is used to retrieve a \em source pipe,
|
|
|
|
|
* which then is treated as if accessing a non-existent mapping: a suitable default
|
|
|
|
|
* solution for this mapping is retrieved, but in this special case, we append the
|
|
|
|
|
* given sequence number to the ID of the retrieved pipe, i.e. we get the Nth
|
|
|
|
|
* (identical) solution to the aforementioned query for a default pipe.
|
|
|
|
|
*
|
2010-11-28 01:43:55 +01:00
|
|
|
* @note the mapped result is remembered within this mapping. Further invocations
|
|
|
|
|
* with the \em same query will just fetch this stored pipe-ID and hand it
|
|
|
|
|
* to the functor, without resolving the query again. You might want to
|
|
|
|
|
* \link Resolver::disconnect remove \endlink this specific mapping
|
|
|
|
|
* in order to force re-evaluation of the query.
|
|
|
|
|
* @param Query for a pipe, which is handed over as-is to the rules engine.
|
|
|
|
|
* @warning depending on the actual query, there might be no solution,
|
|
|
|
|
* in which case an \em unconnected marker is retrieved and
|
|
|
|
|
* stored. Thus the yielded Resolver should be checked,
|
|
|
|
|
* if in doubt.
|
|
|
|
|
*/
|
|
|
|
|
template<class DEF>
|
2010-11-28 02:16:39 +01:00
|
|
|
inline typename OutputMapping<DEF>::Resolver
|
2010-11-28 05:18:57 +01:00
|
|
|
OutputMapping<DEF>::operator[] (Query<asset::Pipe> query4pipe)
|
2010-11-28 02:16:39 +01:00
|
|
|
{
|
|
|
|
|
HashVal hash4query = _mapping::slot (query4pipe);
|
2010-11-28 05:18:57 +01:00
|
|
|
if (!contains (hash4query))
|
|
|
|
|
{
|
|
|
|
|
if (uint seqNr = _mapping::is_defaults_query_with_channel (query4pipe))
|
|
|
|
|
{
|
|
|
|
|
// treat the special case
|
|
|
|
|
// when actually requesting the "Nth default of this kind"
|
|
|
|
|
PPipe corresponding_sourcePipe
|
|
|
|
|
= asset::Pipe::query(
|
|
|
|
|
_mapping::build_corresponding_sourceQuery (query4pipe));
|
|
|
|
|
ENSURE (corresponding_sourcePipe);
|
|
|
|
|
|
|
|
|
|
PId sourcePipeID = corresponding_sourcePipe->getID();
|
|
|
|
|
query4pipe = DEF::buildQuery (sourcePipeID, seqNr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// need to resolve this query first
|
|
|
|
|
table_[hash4query] = _mapping::resolveQuery (query4pipe);
|
|
|
|
|
}
|
2010-11-28 02:16:39 +01:00
|
|
|
|
2010-11-28 05:18:57 +01:00
|
|
|
ENSURE (this->contains (hash4query));
|
2010-11-28 02:16:39 +01:00
|
|
|
return buildResolutionWrapper (hash4query);
|
|
|
|
|
}
|
2010-11-08 04:48:50 +01:00
|
|
|
|
2010-11-25 05:35:50 +01:00
|
|
|
|
2011-12-02 16:10:03 +01:00
|
|
|
}} // namespace proc::mobject
|
2010-11-08 04:48:50 +01:00
|
|
|
#endif
|