WIP some more details on the (planned) Prolog interface --

basically I know enough to provide a mock implementation now.
Compiles OK but fails to link because of missing StructFactory implementation
This commit is contained in:
Fischlurch 2008-01-21 02:57:09 +01:00
parent b0be36c8fb
commit 398bed8d72
4 changed files with 134 additions and 28 deletions

View file

@ -34,12 +34,11 @@ namespace cinelerra
namespace query
{
} // namespace query
/** storage for the Singleton instance factory */
Singleton<query::MockConfigRules> ConfigRules::instance;
} // namespace cinelerra

View file

@ -46,6 +46,11 @@
#include "common/query.hpp"
#include "common/singleton.hpp"
#include "common/typelist.hpp"
#include "proc/mobject/session/track.hpp"
#include "proc/asset/port.hpp"
#include <string>
@ -57,35 +62,23 @@ namespace cinelerra
namespace query { class MockConfigRules; }
/**
* Generic query interface for retrieving objects matching
* some capability query
*/
class ConfigRules
{
protected:
ConfigRules () {}
virtual ~ConfigRules() {}
public:
static Singleton<query::MockConfigRules> instance;
// TODO: find out what operations we need to support here for the »real solution« (using Prolog)
};
namespace query
{
// The intention is to support the following style of Prolog code
//
// retrieve(T) :- type(T, track), find(T), capabilities(T).
// retrieve(T) :- type(T, track), make(T), capabilities(T).
// retrieve(O, Cap) :- find(T), capabilities(Cap).
// retrieve(O, Cap) :- make(T), capabilities(Cap).
// capabilities(Q) :- call(Q).
//
// capabilities(T) :- stream(T,mpeg).
// stream(T, mpeg) :- type(T, track), type(P, port), retrieve(P), place_to(P, T).
// stream(T, mpeg) :- type(T, track), type(P, port), retrieve(P, stream(P,mpeg)), place_to(P, T).
//
// The type guard is inserted auomatically, while the predicate implementations for
// find/1, make/1, stream/2, and place_to/2 are to be provided by the target types.
//
// As a example, the goal ":-retrieve(T, stream(T,mpeg))." would search a Track object, try to
// retrieve a port object with stream-type=mpeg and associate the track with this Port. The
// predicate "stream(P,mpeg)" needs to be implemented (natively) for the port object.
class Resolver
{
@ -118,12 +111,97 @@ namespace cinelerra
template<class TY>
class QueryHandler
{
TY resolve (Query<TY> q);
protected:
virtual ~QueryHandler();
public:
virtual TY resolve (Query<TY> q);
};
// TODO: the Idea is to provide specialisations for the concrete types
// we want to participate in the ConfigRules system....
// Thus we get the possibility to create a specific return type,
// e.g. return a shared_ptr<Port> but a Placement<Track>, using the appropriate factory.
// Of course then the definitions need to be split up in separate headers.
using cinelerra::typelist::Node;
using cinelerra::typelist::NullType;
/**
* Generic query interface for retrieving objects matching
* some capability query. To be instantiated using a typelist,
* thus inheriting from the Handler classes for each type. In
* the (future) version using YAP Prolog, this will drive the
* generation and registration of the necessary predicate
* implementations for each concrete type, using the speicalisations
* given alongside with the types. For now it just serves to generate
* the necessary resolve(Query<TY>) virtual functions (implemented
* by MockConfigRules)
*/
template<class TYPES>
class ConfigRulesInterface;
template<>
class ConfigRulesInterface<NullType>
{
protected:
virtual ~ConfigRulesInterface();
};
template<class TY, typename TYPES>
class ConfigRulesInterface<Node<TY, TYPES> >
: public QueryHandler<TY>,
public ConfigRulesInterface<TYPES>
{ };
template
< typename TYPES,
class IMPL
>
class ConfigRules
: public ConfigRulesInterface<typename TYPES::List>
{
protected:
ConfigRules () {}
virtual ~ConfigRules() {}
public:
static cinelerra::Singleton<IMPL> instance;
// TODO: find out what operations we need to support here for the »real solution« (using Prolog)
};
/** storage for the Singleton instance factory */
template<typename TYPES, class IMPL>
cinelerra::Singleton<IMPL> ConfigRules<TYPES,IMPL>::instance;
} // namespace query
/* ============= global configuration ==================== */
/**
* the list of all concrete types participating in the
* rule based config query system
*/
typedef cinelerra::typelist::Types < mobject::session::Track
, asset::Port
>
InterfaceTypes;
typedef query::ConfigRules< InterfaceTypes, // List of Types to generate interface functions
query::MockConfigRules // actual Implementation to use
>
ConfigRules; // user-visible Interface to the ConfigRules subsystem.
} // namespace cinelerra
#endif

View file

@ -51,18 +51,24 @@ namespace cinelerra
namespace query
{
using mobject::session::Track;
using asset::Port;
/**
* Generic query interface for retrieving objects matching
* some capability query
* Dummy Implementation of the query interface.
* Provides an explicit implementation using hard wired
* values for some types of interest for testing and debugging.
*/
class MockConfigRules : public ConfigRules
class MockConfigRules : public cinelerra::ConfigRules
{
protected:
MockConfigRules ();
friend class cinelerra::singleton::StaticCreate<MockConfigRules>;
public:
virtual Track resolve (Query<Track> q);
virtual Port resolve (Query<Port> q);
};

View file

@ -797,7 +797,7 @@ Error: #f88</pre>
&amp;rarr; [[Configuration Rules system|ConfigRules]]
</pre>
</div>
<div title="ConfigRules" modifier="Ichthyostega" modified="200801181301" created="200801171352" tags="overview spec" changecount="6">
<div title="ConfigRules" modifier="Ichthyostega" modified="200801202311" created="200801171352" tags="overview spec" changecount="7">
<pre>Many features can be implemented by specifically configuring and wiring some unspecific components. Rather than tie the client code in need of some given feature to these configuration internals, in Cinelerra-3 the client can //query // for some kind of object providing the //needed capabilities. // Right from start (summer 2007), Ichthyo had the intention to implement such a feature using sort of a ''declarative database'', e.g. by embedding a Prolog system. By adding rules to the basic session configuration, users should be able to customize the semi-automatic part of Cinelerra's behaviour to great extent.
[[Configuration Queries|ConfigQuery]] are used at various places, when creating and adding new objects, as well when building or optimizing the render engine node network.
@ -815,6 +815,7 @@ Actually posing such an configuration query, for example to the [[Defaults Manag
!Implementation
At start and for debugging/testing, there is an ''dummy'' implementation using a map with predefined queries and answers. But for the real system, the idea is to embed a ''YAP Prolog'' engine to run the queries. This includes the task of defining and loading a set of custom predicates, so the rule system can interact with the object oriented execution environment, for example by transforming some capability predicate into virtual calls to a corresponding object interface. We need a way for objects to declare some capability predicates, together with a functor that can be executed on an object instance (and further parameters) in the cause of the evaluation of some configuration query. Type safety and diagnostics play an important role here, because effectively the rule base is a pool of code open for arbitray additions from the user session.
&amp;rarr; [[considerations for a Prolog based implementation|QueryImplProlog]]
</pre>
</div>
<div title="Controller" modifier="Ichthyostega" modified="200712090624" created="200706220319" tags="def" changecount="4">
@ -2449,6 +2450,28 @@ Like all [[structural assets|StructAsset]], ~ProcPatt employs a special naming s
<pre>a given Render Engine configuration is a list of Processors. Each Processor in turn contains a Graph of ProcNode.s to do the acutal data processing. In order to cary out any calculations, the Processor needs to be called with a StateProxy containing the state information for this RenderProcess
</pre>
</div>
<div title="QueryImplProlog" modifier="Ichthyostega" modified="200801210153" created="200801202321" tags="draft design" changecount="11">
<pre>//obviously, getting this one to work requires quite a lot of technical details to be planned and implemented.// This said...
The intention is to get much more readable (&quot;declarative&quot;) and changeable configuration as by programming it directly within the implementation of some object.
!Draft
As an example, specifying how a Track can be configured for connecting automatically to some &quot;mpeg&quot; bus (=port)
{{{
retrieve(O, Cap) :- find(T), capabilities(Cap).
retrieve(O, Cap) :- make(T), capabilities(Cap).
capabilities(Q) :- call(Q).
stream(T, mpeg) :- type(T, track), type(P, port), retrieve(P, stream(P,mpeg)), place_to(P, T).
}}}
Then, running the goal {{{:-retrieve(T, stream(T,mpeg)).}}} would search a Track object, try to retrieve a port object with stream-type=mpeg and associate the track with this Port. This relies on a predicate &quot;stream(P,mpeg)&quot; implemented (natively) for the port object. So, &quot;Cap&quot; is the query issued from calling code &amp;mdash; here {{{stream(T,mpeg)}}}, the type guard {{{type(T, track)}}} will probably be handled or inserted inserted automatically, while the predicate implementations for find/1, make/1, stream/2, and place_to/2 are to be provided by the target types.
* __The supporting system__ had to combine several code snippets into one rule system to be used for running queries, with some global base rules, rules injected by each individual participating object kind and finally user provided rules added by the current session. The actual query is bound to &quot;Cap&quot; (and consequently run as a goal by {{{call(Q)}}}). The implementation needs to provide a symbol table associating variable terms (like &quot;T&quot; or &quot;P&quot;) to C/C++ object types, enabling the participating object kinds to register their specific predicate implementations. This is crucial, because there can be no general scheme of object-provided predicates (for each object kind different predicates make sense, e.g. [[ports|PortHandling]] have other possibilities than [[wiring requests|WiringRequest]]). Basically, a query issues a Prolog goal, which in turn evaluates domain specific predicates provided by the participating objects and thus calls back into C/C++ code. The supporting system maintains the internal connection (via the &quot;type&quot; predicate) such that from Prolog viewpoint it looks as if we were binding Variables directly to object instances. (there are some nasty technical details because of the backtracking nature of Prolog evaluations which need to be hidden away)
* Any __participating object kind__ needs a way to declare domain specific predicates, thus triggering the registration of the necessary hooks within the supporting system. Moreover, it should be able to inject further prolog code (as shown in the example above with the {{{strem(T, mpeg)}}} predicate. For each of these new domain specific predicates, there needs to be a functor which can be invoked when the C implementation of the predicate is called from Prolog (in some cases even later, when the final solution is &quot;executed&quot;, e.g. a new instance has been created and now some properties need to be set).
!!a note on Plugins
In the design of the Cinelerra-3 Proc Layer done thus far, we provide //no possibility to introduce a new object kind// into the system via plugin interface. The system uses a fixed collection of classes intended to cover all needs (Clip, Effect, Track, Port, Label, Automation, ~Macro-Clips). Thus, plugins will only be able to provide new parametrisations of existing classes. This should not be any real limitation, because the whole system is designed to achieve most of its functionality by freely combining rather basic object kinds. As a plus, it plays nicely with any plain-C based plugin interface. For example, we will have C++ adapter classes for the most common sorts of effect plugin (pull system and synchronous frame-by-frame push with buffering) with a thin C adaptation layer for the specific external plugin systems used.
</pre>
</div>
<div title="RSSReaderPlugin" modifier="Ichthyostega" created="200708081515" tags="systemConfig" changecount="1">
<pre>/***
|''Name:''|RSSReaderPlugin|