WIP work out how some special cases of config queries can be handled.

Including some tricky recursive calls. Even if this is currently a mock implementation it helps me find out
how the real implementation (in Prolog) could handle these cases.
Doesnt pass the compiler yet (some stubs missing)
This commit is contained in:
Fischlurch 2008-04-06 20:11:34 +02:00
parent b53d8655fd
commit 3ed3813be3
4 changed files with 101 additions and 13 deletions

View file

@ -28,9 +28,10 @@
#include "proc/asset/pipe.hpp"
//#include "common/util.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
using util::isnil;
namespace lumiera
@ -101,9 +102,33 @@ namespace lumiera
item<Pipe> (answer_, "pipe(default)") = item<Pipe>(answer_,"pipe(master), stream(video)"); //TODO killme
TODO ("remove the default entries!!! DefaultsManager should find them automatically");
}
/* under some circumstances we need to emulate the behaviour *
* of a real resolution engine in a more detailed manner. *
* These case are hard wired in code below */
/** special case: create a new pipe with matching pipe and stream IDs on the fly when referred... */
bool
MockTable::fabricate_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID)
{
answer_->insert (entry<Pipe> (q, Struct::create (pipeID, streamID)));
}
/** special case: create/retrieve new rocessing pattern for given stream ID... */
bool
MockTable::fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q, string const& streamID)
{
typedef const ProcPatt cPP;
typedef typename WrapReturn<cPP>::Wrapper Ptr;
Ptr newPP (Struct::create (Query<cPP> ("make(PP), "+q)));
answer_->insert (entry<cPP> (q, newPP));
}
MockConfigRules::MockConfigRules ()
{
WARN (config, "using a mock implementation of the ConfigQuery interface");
@ -123,8 +148,8 @@ namespace lumiera
* and with capabilities or properties defined by
* the query. The real implementation would require
* a rule based system (Ichthyo plans to use YAP Prolog),
* while this dummy implementation simply relies on a
* table of pre-fabricated objects. Never fails.
* while this dummy implementation simply relpies based
* on a table of pre-fabricated objects. Never fails.
* @return smart ptr (or similar) holding the object,
* maybe an empty smart ptr if not found
*/
@ -144,9 +169,5 @@ namespace lumiera
} // namespace query
/** */
} // namespace lumiera

View file

@ -38,6 +38,7 @@
#ifndef LUMIERA_MOCKCONFIGRULES_H
#define LUMIERA_MOCKCONFIGRULES_H
#include "proc/mobject/session.hpp"
#include "common/configrules.hpp"
#include "common/util.hpp"
@ -54,8 +55,10 @@ namespace lumiera
namespace query
{
using asset::Pipe;
using asset::ProcPatt;
using asset::PProcPatt;
using mobject::Session;
using util::isnil;
@ -88,6 +91,11 @@ namespace lumiera
MockTable ();
const any& fetch_from_table_for (const string& queryStr);
// special cases....
bool fabricate_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID);
bool fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q, string const& streamID);
private:
void fill_mock_table ();
};
@ -117,14 +125,73 @@ namespace lumiera
)
return solution = candidate;
}
return solution = Ret(); // fail: return default-constructed empty smart ptr
return try_special_case(solution, q);
}
private:
bool
try_special_case (Ret& solution, const Query<TY>& q)
{
Query<TY> newQuery = q;
if (is_defaults_query (q)) // modified query..
return solution = Session::current->defaults (newQuery);
// may cause recursion
if (detect_case (newQuery))
return resolve (solution, newQuery);
return solution = Ret();
// fail: return default-constructed empty smart ptr
}
bool
detect_case (Query<TY>& q);
};
/** Hook for treating very special cases for individual types only */
template<class TY, class BASE>
inline bool
LookupPreconfigured<TY,BASE>::detect_case (Query<TY>& q)
{
q.clear(); // end recursion
return false;
}
template<class BASE>
inline bool
LookupPreconfigured<Pipe,BASE>::detect_case (Query<Pipe>& q)
{
const string pipeID = extractID("pipe", q);
const string streamID = extractID("stream", q);
if (!isnil(pipeID) && !isnil(streamID))
return fabricate_matching_new_Pipe (q, pipeID, streamID);
q.clear();
return false;
}
template<>
inline bool
LookupPreconfigured<const ProcPatt>::detect_case (Query<const ProcPatt>& q)
{
const string streamID = extractID("stream", q);
if (!isnil(streamID))
return fabricate_ProcPatt_on_demand (q, streamID);
// note: we don't handle the case of "make(PP), capabilities....." specially
// because either someone puts a special object into the mock table, or the
// recursive query done by the StructFactory simply fails, resulting in
// the StructFactory issuing a ProcPatt ctor call.
q.clear();
return false;
}
/**
* Dummy Implementation of the query interface.
* Facade: Dummy Implementation of the query interface.
* Provides an explicit implementation using hard wired
* values for some types of interest for testing and debugging.
*/

View file

@ -149,7 +149,7 @@ namespace asset
StructFactoryImpl::fabricate (const Query<Track>& caps)
{
TODO ("actually extract properties/capabilities from the query...");
TODO ("make sure AssetManager detects dublicates (it doesn't currently)");
TODO ("make sure AssetManager detects dublicates (currently 4/08 it doesn't)");
return new Track (createIdent (caps));
}

View file

@ -2267,12 +2267,12 @@ The GUI can connect the viewer(s) to some pipe (and moreover can use [[probe poi
</pre>
</div>
<div title="PipeHandling" modifier="Ichthyostega" modified="200801121656" created="200801101352" tags="spec" changecount="9">
<div title="PipeHandling" modifier="Ichthyostega" modified="200804061705" created="200801101352" tags="spec" changecount="10">
<pre>!Identification
Pipes are distinct objects and can be identified by their asset ~IDs. Besides, as for all [[structural assets|StructAsset]] there are extended query capabilities, including a symbolic pipe-id and a media (stream) type id. Any pipe can accept and deliver exactly one media stream kind (which may be inherently structured though, e.g. spatial sound systems or stereoscopic video)
!creating pipes
Pipe assets are created automatically by being used and referred. The [[Session]] holds a collection of global pipes, and further pipes can be created by using an new pipe reference in some placement. Moreover, every clip has an (implicit) [[source port|ClipSourcePort]], which will appear as pipe asset when first used (referred) while [[building|BuildProcess]].
Pipe assets are created automatically by being used and referred. The [[Session]] holds a collection of global pipes, and further pipes can be created by using a new pipe reference in some placement. Moreover, every clip has an (implicit) [[source port|ClipSourcePort]], which will appear as pipe asset when first used (referred) while [[building|BuildProcess]]. Note that creating a new pipe implies using a [[processing pattern|ProcPatt]], which will be queried from the [[Defaults Manager|DefaultsManagement]] (resulting in the use of some preconfigured pattern or maybe the creation of a new ProcPatt object if necessary)
!removal
Deleting a Pipe is an advanced operation, because it includes finding and &quot;detaching&quot; all references, otherwise the pipe will leap back into existence immediately. Thus, global pipe entries in the Session and pipe references in [[locating pins|LocatingPin]] within any placement have to be removed, while clips using a given source port will be disabled. {{red{todo: implementation deferred}}}