implement builder/accesor function; adapt StructFactory

This commit is contained in:
Fischlurch 2012-12-09 02:42:36 +01:00
parent 8630e888a5
commit 08ff817afd
6 changed files with 82 additions and 41 deletions

View file

@ -33,13 +33,25 @@
** Fully implementing this facility would require the participating objects to register capabilities
** they want to provide, together with functors carrying out the necessary configuration steps.
** All details and consequences of this approach still have to be worked out...
**
** \par relation to Query and QueryResolver
** The ConfigRules resolver is just a special kind of QueryResolver, able to handle specific kinds
** of queries. Clients using the ConfigRules directly get a more easy to use point-and-shot style
** interface, allowing just to retrieve some \em suitable solution, instead of having to iterate
** through a result set.
**
** @todo right now (12/2012) the above paragraph is a lie.
** ConfigQuery is way older than QueryResolver and will be retrofitted step by step.
** Not much of a problem, since the currently utilised mock implementation isn't able to
** deal with a real query anyway.
**
** @note this is rather a scrapbook and in flux... don't take this code too literal!
** @note this is rather a concept draft and left as such for now... don't take this code too literal!
** @todo clarify the relation of config query and query-for-defaults ///////////////TICKET #705
**
** @see lumiera::Query
** @see mobject::session::DefsManager
** @see asset::StructFactory
** @see config-resolver.hpp specialised setup for the Proc-Layer
** @see fake-configrules.hpp currently used dummy-implementation
** @see
**
@ -137,6 +149,7 @@ namespace lumiera {
* type TY fulfilling the given Query. To start with,
* we use a mock implementation.
* (this code works and is already used 2/2008)
* @todo retrofit this to install and use a QueryResolver
* @see lumiera::query::LookupPreconfigured
* @see lumiera::query::MockTable
*/

View file

@ -29,6 +29,7 @@
#include "lib/typed-counter.hpp"
#include "lib/iter-adapter.hpp"
#include "lib/query-text.hpp"
#include "lib/query-util.hpp"
#include "lib/nocopy.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
@ -243,6 +244,12 @@ namespace lumiera {
Builder
rebuild() const;
string
extractID (Symbol predicate) const
{
return this->rebuild().extractID (predicate);
}
/* results retrieval */
class Cursor
@ -266,6 +273,7 @@ namespace lumiera {
iterator operator() (QueryResolver const& resolver) const;
iterator resolveBy (QueryResolver const& resolver) const;
friend size_t
hash_value (Query const& q)
{
@ -282,34 +290,50 @@ namespace lumiera {
/**
* Helper for establishing,
* reworking and remolding queries.
*/
template<class RES>
class Query<RES>::Builder
{
QueryID typeID_;
string predicateForm_;
Builder (QueryID kind, string baseDef ="")
: typeID_(kind)
, predicateForm_(baseDef)
{ }
friend class Query<RES>;
public:
const string
/**
* Helper for establishing,
* reworking and remolding queries.
*/
template<class RES>
class Query<RES>::Builder
{
QueryID typeID_;
string predicateForm_;
Builder (QueryID kind, string baseDef ="")
: typeID_(kind)
, predicateForm_(baseDef)
{ }
friend class Query<RES>;
public:
string
asKey() const
{
return "type("
+ lexical_cast<string> (getResultTypeID<RES>())
+ "), "+predicateForm_;
}
};
string
extractID (Symbol predicate) const
{
return lib::query::extractID (predicate, this->predicateForm_);
}
};
template<class RES>
typename Query<RES>::Builder
Query<RES>::rebuild() const
{
return Builder(this->id_, this->def_);
}

View file

@ -115,11 +115,9 @@ namespace asset {
createIdent (Query<STRU> const& query)
{
// does the query somehow specify the desired name-ID?
string nameID = "TODO";//extractID (genericIdSymbol, query);////////////////////////////////////////////////////////////////////////////////////////////TODO
UNIMPLEMENTED("Query rebuilding");////////////////////////////////////////////////////////////////////////////////////////////TODO
string nameID = query.extractID (genericIdSymbol);
if (isnil (nameID))
nameID = "TODO";//extractID (StructTraits<STRU>::idSymbol(), query);////////////////////////////////////////////////////////////////////////////////////////////TODO
UNIMPLEMENTED("Query rebuilding");////////////////////////////////////////////////////////////////////////////////////////////TODO
nameID = query.extractID (StructTraits<STRU>::idSymbol());
if (isnil (nameID))
{
// no name-ID contained in the query...
@ -131,8 +129,7 @@ namespace asset {
ENSURE (!isnil (nameID));
// does the query actually demand the Nth instance/element?
string seqID = "TODO";//extractID (seqNrPredicate, query);////////////////////////////////////////////////////////////////////////////////////////////TODO
UNIMPLEMENTED("Query rebuilding");////////////////////////////////////////////////////////////////////////////////////////////TODO)
string seqID = query.extractID (seqNrPredicate);
if (!isnil (seqID) && 1 < asNumber(seqID))
nameID += "."+seqID;
@ -205,8 +202,7 @@ namespace asset {
StructFactoryImpl::fabricate (Query<Pipe> const& caps)
{
const Asset::Ident idi (createIdent (caps));
string streamID = "TODO";//extractID ("stream", caps);////////////////////////////////////////////////////////////////////////////////////////////TODO
UNIMPLEMENTED("fabricate a Pipe by query");////////////////////////////////////////////////////////////////////////////////////////////TODO
string streamID = caps.extractID ("stream");
if (isnil (streamID)) streamID = "default";
PProcPatt processingPattern = Session::current->defaults (Query<const ProcPatt>("stream("+streamID+")"));
return new Pipe( idi
@ -221,7 +217,7 @@ namespace asset {
{
TODO ("extract additional properties/capabilities from the query...");
const Asset::Ident idi (createIdent (caps));
string sequenceID = "TODO";//extractID ("sequence", caps);////////////////////////////////////////////////////////////////////////////////////////////TODO
string sequenceID = caps.extractID ("sequence");
UNIMPLEMENTED("fabricate a Timeline by query");////////////////////////////////////////////////////////////////////////////////////////////TODO
Query<Sequence> desiredSequence (isnil (sequenceID)? "" : "id("+sequenceID+")");
PSequence sequence = recursive_create_(desiredSequence);
@ -239,7 +235,7 @@ namespace asset {
{
// when we reach this point it is clear a suitable sequence doesn't yet exist in the model
TODO ("actually extract properties/capabilities from the query...");
string trackID = "TODO";//extractID ("track", caps);////////////////////////////////////////////////////////////////////////////////////////////TODO
string trackID = caps.extractID ("track");
UNIMPLEMENTED("fabricate a Sequence by query");////////////////////////////////////////////////////////////////////////////////////////////TODO
Query<Track> desiredTrack (isnil (trackID)? "" : "id("+trackID+")");
// PTrack track = Session::current->query (desiredTrack); ///////////////////////////////////TICKET #639

View file

@ -72,6 +72,8 @@ namespace asset {
* @throw error::Invalid in case of ID clash with an existing Asset
* @return an Struct smart ptr linked to the internally registered smart ptr
* created as a side effect of calling the concrete Struct subclass ctor.
* @todo using the AssetManager this way for picking up the previously stored
* asset is a code smell ////////////////////////////TICKET #691
*/
template<class STRU>
P<STRU>
@ -84,17 +86,19 @@ namespace asset {
/** Retrieve a suitable Structural Asset instance, possibly create.
/** Retrieve a suitable Structural Asset instance, possibly create one.
* First tries to resolve the asset by issuing an capability query.
* If unsuccessful, use some internally specialised ctor call.
* @todo work out the struct asset naming scheme! /////////////////////////////////TICKET #565
* @todo for now we're using a faked config query, just pulling preconfigured
* hardwired answers from a table. Should be replaced by a real resolution engine.
* @note the exact calling sequence implemented here can be considered a compromise,
* due to not having neither a working resolution, nor a generic interface for
* due to having neither a working resolution, nor a generic interface for
* issuing queries. Thus, directly calling this factory acts as a replacement
* for both. The final algorithm to be implemented later should fabricate
* \em first, and then then query as a second step to define the capabilities.
* for both. The intended solution would be to have a dedicated QueryResolver,
* which is fully integrated into a generic rules driven query subsystem, but
* has the additional ability to "translate" capabilities directly into the
* respective properties of of asset::Struct subclasses.
* @return an Struct smart ptr linked to the internally registered smart ptr
* created as a side effect of calling the concrete Struct subclass ctor.
*/

View file

@ -144,8 +144,6 @@ namespace asset {
public:
typedef P<asset::Struct> PType;
template<class STRU>
P<STRU> operator() (Query<STRU> const& query);

View file

@ -28,7 +28,13 @@
** These classes are placed into namespace asset and proc_interface.
**
** @todo 10/10 meanwhile I'm unhappy with some aspects of this implementation //////////////TICKET #691
**
** @todo 12/12 and meanwhile I'm way more unhappy with the whole design. Looks like I wasn't proficient
** enough with OO design in C++ when writing that original design. Especially, this design
** couples the object creation, the memory management and the registration way too tightly.
** Having a registration magic in the asset baseclass ctor is just too clever and a half.
** Rather, there should be a responsibility chain, using completely passive Asset objects:
** Factory -> AssetManaager -> Asset object
**
** @see asset.hpp
** @see mobject.hpp
*/
@ -108,7 +114,7 @@ namespace asset {
/** deleter function used by the Asset smart pointers to delete Asset objects */
static void destroy (Asset* aa) { delete aa; }
friend Asset::Asset (const Asset::Ident& idi);
friend Asset::Asset (Asset::Ident const& idi);
AssetManager ();