From 08ff817afd5ad4fbb98e2da0476aa67179876b64 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 9 Dec 2012 02:42:36 +0100 Subject: [PATCH] implement builder/accesor function; adapt StructFactory --- src/common/config-rules.hpp | 15 +++++- src/common/query.hpp | 68 +++++++++++++++++--------- src/proc/asset/struct-factory-impl.hpp | 16 +++--- src/proc/asset/struct.cpp | 12 +++-- src/proc/asset/struct.hpp | 2 - src/proc/assetmanager.hpp | 10 +++- 6 files changed, 82 insertions(+), 41 deletions(-) diff --git a/src/common/config-rules.hpp b/src/common/config-rules.hpp index 837e0acaa..f9fe4a7f4 100644 --- a/src/common/config-rules.hpp +++ b/src/common/config-rules.hpp @@ -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 */ diff --git a/src/common/query.hpp b/src/common/query.hpp index 27d666693..e3bd1f537 100644 --- a/src/common/query.hpp +++ b/src/common/query.hpp @@ -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 Query::Builder - { - QueryID typeID_; - string predicateForm_; - - Builder (QueryID kind, string baseDef ="") - : typeID_(kind) - , predicateForm_(baseDef) - { } - - friend class Query; - - - public: - - const string + /** + * Helper for establishing, + * reworking and remolding queries. + */ + template + class Query::Builder + { + QueryID typeID_; + string predicateForm_; + + Builder (QueryID kind, string baseDef ="") + : typeID_(kind) + , predicateForm_(baseDef) + { } + + friend class Query; + + + public: + + string asKey() const { return "type(" + lexical_cast (getResultTypeID()) + "), "+predicateForm_; } - }; + + + string + extractID (Symbol predicate) const + { + return lib::query::extractID (predicate, this->predicateForm_); + } + + }; + + + template + typename Query::Builder + Query::rebuild() const + { + return Builder(this->id_, this->def_); + } diff --git a/src/proc/asset/struct-factory-impl.hpp b/src/proc/asset/struct-factory-impl.hpp index 36241e789..b828413c4 100644 --- a/src/proc/asset/struct-factory-impl.hpp +++ b/src/proc/asset/struct-factory-impl.hpp @@ -115,11 +115,9 @@ namespace asset { createIdent (Query 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::idSymbol(), query);////////////////////////////////////////////////////////////////////////////////////////////TODO - UNIMPLEMENTED("Query rebuilding");////////////////////////////////////////////////////////////////////////////////////////////TODO + nameID = query.extractID (StructTraits::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 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("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 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 desiredTrack (isnil (trackID)? "" : "id("+trackID+")"); // PTrack track = Session::current->query (desiredTrack); ///////////////////////////////////TICKET #639 diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp index 9a9d5eade..136451a2d 100644 --- a/src/proc/asset/struct.cpp +++ b/src/proc/asset/struct.cpp @@ -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 P @@ -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. */ diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index ebd9fbb5b..64b7ce616 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -144,8 +144,6 @@ namespace asset { public: - typedef P PType; - template P operator() (Query const& query); diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 61567c582..2dc983f23 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -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 ();