fake-configrules: remove magic "make" token (closes #707)

use backdoor function on the StructFactory instead
Mark such backdoor-functions with Ticket #710
This commit is contained in:
Fischlurch 2010-11-02 04:09:06 +01:00
parent 1f511c327a
commit 4cef8474ed
8 changed files with 53 additions and 29 deletions

View file

@ -57,6 +57,7 @@ namespace lumiera {
void setFakeBypass(string const& q) { fakeBypass = q; }
bool isFakeBypass (string const& q) { return q == fakeBypass; }
/////////////////////////////////////////////////////////////////////////////TICKET 710
} // namespace query

View file

@ -244,6 +244,7 @@ namespace lumiera { ///////TODO: shouldn't that be namespace lib? or proc?
* as the query system is not able to do real query resolution */
void setFakeBypass(string const& q);
bool isFakeBypass (string const& q);
/////////////////////////////////////////////////////////////////////////////TICKET 710
} // namespace query

View file

@ -35,6 +35,7 @@
using util::isnil;
//////////////////////////////////////////////////////////////////TICKET #710 : to be removed entirely in Alpha
namespace lumiera {
@ -135,7 +136,7 @@ namespace lumiera {
{
typedef WrapReturn<Pipe>::Wrapper Ptr;
Ptr newPipe (Struct::retrieve (Query<Pipe> (string("make(PP), ")+q)));
Ptr newPipe (Struct::retrieve.made4fake (q));
answer_->insert (entry<Pipe> (q, newPipe));
return true;
}
@ -147,12 +148,15 @@ namespace lumiera {
typedef const ProcPatt cPP;
typedef WrapReturn<cPP>::Wrapper Ptr;
Ptr newPP (Struct::retrieve (Query<cPP> ("make(PP), "+q))); // magic token: bail out and invoke factory for new object
Ptr newPP (Struct::retrieve.made4fake (q));
answer_->insert (entry<cPP> (q, newPP));
return true;
}
/** special case: fabricate new Timeline, maybe using ID specs from the query... */
/** special case: fabricate new Timeline, maybe using specific sub-objects
* as hinted by the IDs given within the query. This might include searching
* the session's timelines / sequences to retrieve an existing object
* with matching ID... */
bool
MockTable::fabricate_Timeline_on_demand (Query<asset::Timeline>& query)
{
@ -176,10 +180,10 @@ namespace lumiera {
break;
}
if (!newTimeline) // no suitable Timeline found: create and attach new one
newTimeline = Struct::retrieve (Query<aTl> ("make(TL), "+query));
// "make" magic token: bail out and invoke factory for new object
answer_->insert (entry<aTl> (query, newTimeline)); // learn the found/created Timeline as new solution
if (!newTimeline)
newTimeline = Struct::retrieve.made4fake (query); // no suitable Timeline found: create and attach new one
answer_->insert (entry<aTl> (query, newTimeline)); // "learn" the found/created Timeline as new solution
return true;
}
@ -208,7 +212,7 @@ namespace lumiera {
}
if (!newSequence)
newSequence = Struct::retrieve (Query<aSq> ("make(SQ), "+query)); // no suitable found: create and attach new Sequence
newSequence = Struct::retrieve.made4fake (query); // no suitable found: create and attach new Sequence
answer_->insert (entry<aSq> (query, newSequence));
return true;

View file

@ -28,7 +28,9 @@
** as answer values. As of 1/2008 it is used to "keep the implementation work going"
** -- later on, when we use a real Prolog interpreter, it still may be useful for
** testing and debugging.
**
**
** @todo to be removed in Alpha, when integrating a real resolution engine /////////////////TICKET #710
**
** @see lumiera::Query
** @see lumiera::ConfigRules
**
@ -109,7 +111,7 @@ namespace lumiera {
template<class TY>
bool detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q);
bool fabricate_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID);
bool fabricate_just_new_Pipe (Query<Pipe>& q);
bool fabricate_just_new_Pipe (Query<Pipe>& q);
bool fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q);
bool fabricate_Timeline_on_demand (Query<asset::Timeline>& q);
bool fabricate_Sequence_on_demand (Query<asset::Sequence>& q);
@ -182,9 +184,8 @@ namespace lumiera {
MockTable::detect_case (WrapReturn<Pipe>::Wrapper& candidate, Query<Pipe>& q)
{
if (!isnil (extractID("make", q)))
return false; // let the query fail here,
// so the invoking factory will go ahead
// and create a new object. (prevents infinite recursion)
// used by tests to force fabrication of a new "solution"
return fabricate_just_new_Pipe (q);
const string pipeID = extractID("pipe", q);
const string streamID = extractID("stream", q);
@ -205,10 +206,8 @@ namespace lumiera {
inline bool
MockTable::detect_case (WrapReturn<const ProcPatt>::Wrapper& candidate, Query<const ProcPatt>& q)
{
if (!isnil (extractID("make", q)))
return false; // failure triggers creation...
const string streamID = extractID("stream", q);
if (!candidate && !isnil(streamID))
return fabricate_ProcPatt_on_demand (q);
@ -219,9 +218,6 @@ namespace lumiera {
inline bool
MockTable::detect_case (WrapReturn<asset::Timeline>::Wrapper& candidate, Query<asset::Timeline>& q)
{
if (!isnil (extractID("make", q)))
return false; // failure triggers creation...
if (!candidate)
return fabricate_Timeline_on_demand (q);
@ -232,9 +228,6 @@ namespace lumiera {
inline bool
MockTable::detect_case (WrapReturn<asset::Sequence>::Wrapper& candidate, Query<asset::Sequence>& q)
{
if (!isnil (extractID("make", q)))
return false; // failure triggers creation...
if (!candidate)
return fabricate_Sequence_on_demand (q);

View file

@ -60,8 +60,8 @@ namespace lumiera {
return string(typeid(OBJ).name())+": "+*this;
}
operator string& () { return *this; } // TODO: needed temporarily by fake-configrules
}; // for calling removeTerm on the string-ref....
operator string& () { return *this; } //TICKET #710 : needed temporarily by fake-configrules
}; // for calling removeTerm on the string-ref....
namespace query {

View file

@ -113,6 +113,24 @@ namespace asset {
}
////////////////////////////////////////////////////////////////////////////////////TICKET #710 : backdoor for fake-configrules
/** special backdoor for fake-configrules.hpp
* This allows to simulate creation of objects triggered by rules.
* Actually we use just a fake implementation based on a table lookup
* plus some hard wired special cases, which need to call in here to
* fabricate new objects, which can then be used as "solutions".
* @param query a prolog like query string
* @note works quite similar like the #operator(), but without
* re-invoking the ConfigRules....
*/
template<class STRU>
P<STRU>
StructFactory::made4fake (Query<STRU> const& query)
{
STRU* pS = impl_->fabricate(query);
return AssetManager::instance().wrap (*pS);
}
////////////////////////////////////////////////////////////////////////////////////TICKET #710 : backdoor for fake-configrules
/** Factory method for creating Pipes explicitly.
@ -155,15 +173,19 @@ namespace asset {
namespace asset {
template P<Pipe> StructFactory::operator() (const Query<Pipe>& query);
template PProcPatt StructFactory::operator() (const Query<const ProcPatt>& query);
template PTimeline StructFactory::operator() (const Query<Timeline>& query);
template PSequence StructFactory::operator() (const Query<Sequence>& query);
template P<Pipe> StructFactory::operator() (Query<Pipe> const&);
template PProcPatt StructFactory::operator() (Query<const ProcPatt> const&);
template PTimeline StructFactory::operator() (Query<Timeline> const&);
template PSequence StructFactory::operator() (Query<Sequence>const&);
template P<Pipe> StructFactory::newInstance (Symbol);
template PProcPatt StructFactory::newInstance (Symbol);
template PTimeline StructFactory::newInstance (Symbol);
template PSequence StructFactory::newInstance (Symbol);
template P<Pipe> StructFactory::made4fake (Query<Pipe> const&);
template PProcPatt StructFactory::made4fake (Query<const ProcPatt> const&);
template PTimeline StructFactory::made4fake (Query<Timeline> const&);
template PSequence StructFactory::made4fake (Query<Sequence>const&);
} // namespace asset

View file

@ -156,6 +156,9 @@ namespace asset {
template<class STRU>
P<STRU> newInstance (Symbol nameID ="");
template<class STRU>
P<STRU> made4fake (Query<STRU> const& query); ///< @warning to be removed in Alpha when using a real resolution engine /////TICKET #710
P<Pipe> newPipe (string pipeID, string streamID);
};

View file

@ -166,7 +166,7 @@ namespace test {
// this is fine but doesn't work as long as there is another entry in the mock table...
// ...for now we use a hack to overwrite the reference in the mock table
//
ASSERT (3 == pipe1.use_count()); // that's the problem; it should be 2
ASSERT (3 == pipe1.use_count()); // that's the problem; it should be 2 (the pipe1 smart-ptr and the AssetManager)
QueryHandler<Pipe>& typeHandler = ConfigRules::instance();
PPipe pipe2 = asset::Struct::retrieve.newPipe (pID, "quatsch");