refactor namespaces for query and defaults manager

This commit is contained in:
Fischlurch 2012-12-01 08:44:07 +01:00
parent 8ee8eb1e73
commit 5dfe5e099f
70 changed files with 366 additions and 546 deletions

View file

@ -90,20 +90,21 @@
*/
#ifndef LIB_ADVICE_H
#define LIB_ADVICE_H
#ifndef LUMIERA_ADVICE_H
#define LUMIERA_ADVICE_H
#include "lib/error.hpp"
#include "lib/null-value.hpp"
#include "lib/advice/binding.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include "common/advice/binding.hpp"
#include <boost/noncopyable.hpp>
namespace lib {
namespace lumiera{
namespace advice {
using lib::Symbol;
@ -227,7 +228,7 @@ namespace advice {
* piece of advice they're looking for.
*
* Any advice::Provision remains inactive and thus invisible, until
* \link #setAdvice setting the concrete advice data \endlink. After that,
* \link #setAdvice setting the concrete advice data.\endlink After that,
* the provided data is \em copied into the AdviceSystem and remains available
* even after the original Provision goes out of scope. Consequently, it isn't
* possible to \em modify advice data once set. But client code may retract
@ -271,6 +272,7 @@ namespace advice {
AdviceLink::operator= (o);
setSolution ( NULL );
}
return *this;
}
@ -433,7 +435,7 @@ namespace advice {
AD const&
handleMissingSolution() const ///< @warning might segfault when used during shutdown
{
return NullValue<AD>::get();
return lib::NullValue<AD>::get();
}
@ -477,5 +479,5 @@ namespace advice {
}} // namespace lib::advice
}} // namespace lumiera::advice
#endif

View file

@ -90,25 +90,26 @@
#include "lib/error.hpp"
#include "lib/advice.hpp"
#include "lib/advice/index.hpp"
#include "lib/del-stash.hpp"
#include "lib/singleton.hpp"
#include "lib/symbol.hpp"
#include "lib/sync.hpp"
#include "lib/util.hpp"
#include "include/logging.h"
#include "common/advice.hpp"
#include "common/advice/index.hpp"
#include <boost/noncopyable.hpp>
using lib::Symbol;
using lib::Singleton;
using lib::DelStash;
using util::unConst;
typedef void (DeleterFunc)(void*);
namespace lib {
namespace lumiera{
namespace advice {
namespace { // ======= implementation of the AdviceSystem ============
@ -159,6 +160,8 @@ namespace advice {
{
throw error::Fatal("Unable to store Advice due to memory exhaustion");
}
ERROR_LOG_AND_IGNORE (memory, "Storing a piece of Advice")
throw error::Fatal("Unable to store Advice data");
}
void

View file

@ -21,9 +21,9 @@
* *****************************************************/
#include "lib/advice/binding.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include "lib/symbol.hpp"
#include "common/advice/binding.hpp"
#include <boost/functional/hash.hpp>
#include <boost/lexical_cast.hpp>
@ -41,7 +41,7 @@ using boost::hash_combine;
using boost::lexical_cast;
namespace lib {
namespace lumiera{
namespace advice {
LUMIERA_ERROR_DEFINE (BINDING_PATTERN_SYNTAX, "Unable to parse the given binding pattern definition");
@ -191,4 +191,4 @@ namespace advice {
}} // namespace lib::advice
}} // namespace lumiera::advice

View file

@ -55,6 +55,8 @@
** the symbolic definition is parsed, then normalised and finally, after creating the matcher
** functor, the full pattern definition can be discarded.
**
** @remarks while binding is defined in the context of the advice system for now,
** obviously this is the foundation of a more generic system to deal with predicate terms.
** @note as of 4/2010 this is an experimental setup and implemented just enough to work out
** the interfaces. Ichthyo expects this collaboration service to play a central role
** at various places within proc-layer.
@ -69,21 +71,22 @@
*/
#ifndef LIB_ADVICE_BINDING_H
#define LIB_ADVICE_BINDING_H
#ifndef LUMIERA_ADVICE_BINDING_H
#define LUMIERA_ADVICE_BINDING_H
#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include <iostream>
#include <string>
#include <set>
namespace lib {
namespace lumiera{
namespace advice {
using lib::Literal;
using std::string;
typedef size_t HashVal;
@ -228,7 +231,7 @@ namespace advice {
inline Binding const&
Binding::addTypeGuard()
{
atoms_.insert (Atom ("advice.type."+lib::query::buildTypeID<TY>()));
atoms_.insert (Atom ("advice.type."+lumiera::query::buildTypeID<TY>()));
return *this;
}
@ -297,5 +300,5 @@ namespace advice {
}} // namespace lib::advice
}} // namespace lumiera::advice
#endif

View file

@ -83,24 +83,24 @@
*/
#ifndef LIB_ADVICE_INDEX_H
#define LIB_ADVICE_INDEX_H
#ifndef LUMIERA_ADVICE_INDEX_H
#define LUMIERA_ADVICE_INDEX_H
#include "lib/error.hpp"
#include "lib/advice/binding.hpp"
#include "lib/symbol.hpp"
#include "include/logging.h"
#include "lib/iter-adapter-stl.hpp"
#include "lib/util-foreach.hpp"
#include "lib/util.hpp"
#include "common/advice/binding.hpp"
#include <boost/operators.hpp>
#include <tr1/unordered_map>
#include <iostream>
#include <string>
namespace lib {
namespace lumiera{
namespace advice {
namespace error = lumiera::error;
@ -249,7 +249,7 @@ namespace advice {
cout << "E...:"<< (*i) << endl;
}
RangeIter<EIter>
lib::RangeIter<EIter>
allElms ()
{
return eachElm (elms_);
@ -591,5 +591,5 @@ namespace advice {
#undef VERIFY
}} // namespace lib::advice
}} // namespace lumiera::advice
#endif

View file

@ -1,5 +1,5 @@
/*
CONFIGRULES.hpp - interface for rule based configuration
CONFIG-RULES.hpp - interface for rule based configuration
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -21,7 +21,7 @@
*/
/** @file configrules.hpp
/** @file config-rules.hpp
** Interface for accessing rule based configuration.
** By using the Query template, you can pose a query in prolog syntax and get some
** existing or newly created object fulfilling the requested predicates. The actual
@ -46,33 +46,25 @@
*/
#ifndef LUMIERA_CONFIGRULES_H
#define LUMIERA_CONFIGRULES_H
#ifndef LUMIERA_CONFIG_RULES_H
#define LUMIERA_CONFIG_RULES_H
#include "lib/p.hpp"
#include "lib/query.hpp"
#include "lib/symbol.hpp"
#include "lib/meta/generator.hpp"
#include "lib/singleton-subclass.hpp"
//TODO: is it sensible to bring in the types explicitly here? (it's not necessary, but may be convenient...)
#include "proc/mobject/session/track.hpp"
#include "proc/asset/procpatt.hpp"
#include "proc/asset/pipe.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "common/query.hpp"
#include <string>
namespace lumiera { ///////TODO: shouldn't that be namespace lib? or proc?
namespace lumiera {
using std::string;
using lib::P;
/////////////////////////////////////////////////////////////////////TICKET #705 this is draft/preview code; a real resolution system needs to be integrated
namespace query {
@ -93,13 +85,13 @@ namespace lumiera { ///////TODO: shouldn't that be namespace lib? or proc?
class Resolver
{
///////////////////////////////////////////////////////////////TICKET #705 a real resolution system needs to be integrated
};
using lib::Symbol;
using lib::Literal;
using lib::Query;
using lumiera::Query;
/** placeholder definition for later.
* @todo intention is to integrate with lib::Symbol
@ -208,34 +200,6 @@ namespace lumiera { ///////TODO: shouldn't that be namespace lib? or proc?
/* ============= global configuration ==================== */
/**
* the list of all concrete types participating in the
* rule based config query system
*/
typedef lib::meta::Types < proc::mobject::session::Track
, proc::asset::Pipe
, const proc::asset::ProcPatt
, proc::asset::Timeline
, proc::asset::Sequence
> ::List
InterfaceTypes;
/**
* user-visible Interface to the ConfigRules subsystem.
* Configured as Singleton (with hidden Implementation class)
*/
class ConfigRules
: public query::ConfigRules<InterfaceTypes>
{
public:
static lib::SingletonSub<ConfigRules> instance;
};
namespace query {

View file

@ -39,7 +39,7 @@
#include <string>
namespace lib {
namespace lumiera {
using lib::IxID;
using lib::Symbol;

View file

@ -23,7 +23,7 @@
#include "lib/error.hpp"
#include "common/configrules.hpp"
#include "common/config-rules.hpp"
#include "proc/mobject/session/query/fake-configrules.hpp"
@ -36,16 +36,6 @@ namespace lumiera {
} // namespace query
namespace {
/** type of the actual ConfigRules implementation to use */
lib::singleton::UseSubclass<proc::mobject::session::query::MockConfigRules> typeinfo;
}
/** Singleton factory instance, parametrised to actual impl. type. */
lib::SingletonSub<ConfigRules> ConfigRules::instance (typeinfo);
@ -59,8 +49,5 @@ namespace lumiera {
bool isFakeBypass (string const& q) { return q == fakeBypass; }
/////////////////////////////////////////////////////////////////////////////TICKET 710
} // namespace query
}// namespace query
} // namespace lumiera

View file

@ -1,5 +1,5 @@
/*
DefsManager - access to preconfigured default objects and definitions
DEFS-MANAGER-IMPL.h - access to preconfigured default objects and definitions
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -18,25 +18,46 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
*/
#include "proc/mobject/session/defs-manager.hpp"
#include "proc/mobject/session/defs-registry.hpp"
#include "common/configrules.hpp"
/** @file defs-manager-impl.hpp
** Implementation of the core defaults-management operations.
** These generic implementations are factored out into a separate header (include)
** to improve readability. To actually generate code, it is necessary to pull in this
** include to create explicit template instantiations with the concrete types to be used
** for definition and retrieval of default-configured objects.
**
** For the standard use-case within the session / Proc-Layer, this is performed for the
** core MObject types, alongside with the definition of the generic config-query-resolver.
**
** @see config-resolver.cpp definition of the explicit specialisiations for the session
** @see proc::ConfigResolver
**
*/
#ifndef LUMIERA_QUERY_DEFS_MANAGER_IMPL_H
#define LUMIERA_QUERY_DEFS_MANAGER_IMPL_H
#include "common/query/defs-manager.hpp"
#include "common/query/defs-registry.hpp"
#include "common/config-rules.hpp"
#include "lib/format-string.hpp"
#include "lib/error.hpp"
using util::_Fmt;
using lumiera::ConfigRules;
using proc::ConfigResolver;
using lumiera::query::QueryHandler;
using lumiera::query::LUMIERA_ERROR_CAPABILITY_QUERY;
namespace proc {
namespace mobject {
namespace session {
namespace lumiera{
namespace query {
@ -61,7 +82,7 @@ namespace session {
DefsManager::search (const Query<TAR>& capabilities)
{
P<TAR> res;
QueryHandler<TAR>& typeHandler = ConfigRules::instance();
QueryHandler<TAR>& typeHandler = ConfigResolver::instance();
for (DefsRegistry::Iter<TAR> i = defsRegistry->candidates(capabilities);
bool(*i) ; ++i )
{
@ -79,7 +100,7 @@ namespace session {
DefsManager::create (const Query<TAR>& capabilities)
{
P<TAR> res;
QueryHandler<TAR>& typeHandler = ConfigRules::instance();
QueryHandler<TAR>& typeHandler = ConfigResolver::instance();
typeHandler.resolve (res, capabilities);
if (res)
defsRegistry->put (res, capabilities);
@ -92,7 +113,7 @@ namespace session {
DefsManager::define (const P<TAR>& defaultObj, const Query<TAR>& capabilities)
{
P<TAR> candidate (defaultObj);
QueryHandler<TAR>& typeHandler = ConfigRules::instance();
QueryHandler<TAR>& typeHandler = ConfigResolver::instance();
typeHandler.resolve (candidate, capabilities);
if (!candidate)
return false;
@ -128,48 +149,5 @@ namespace session {
return res;
}
}}} // namespace mobject::session
/***************************************************************/
/* explicit template instantiations for querying various Types */
/***************************************************************/
#include "proc/asset/procpatt.hpp"
#include "proc/asset/pipe.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "proc/mobject/session/track.hpp"
namespace proc {
namespace mobject {
namespace session {
using asset::Pipe;
using asset::PPipe;
using asset::ProcPatt;
using asset::PProcPatt;
using asset::Timeline;
using asset::PTimeline;
using asset::Sequence;
using asset::PSequence;
using mobject::session::Track;
using mobject::session::PTrack;
template PPipe DefsManager::operator() (Query<Pipe> const&);
template PProcPatt DefsManager::operator() (Query<const ProcPatt> const&);
template PTrack DefsManager::operator() (Query<Track> const&);
template PTimeline DefsManager::operator() (Query<Timeline> const&);
template PSequence DefsManager::operator() (Query<Sequence> const&);
template bool DefsManager::define (PPipe const&, Query<Pipe> const&);
template bool DefsManager::forget (PPipe const&);
}}} // namespace proc::mobject::session
}} // namespace lumiera::query
#endif /* LUMIERA_QUERY_DEFS_MANAGER_IMPL_H */

View file

@ -21,25 +21,24 @@
*/
#ifndef PROC_MOBJECT_SESSION_DEFS_MANAGER_H
#define PROC_MOBJECT_SESSION_DEFS_MANAGER_H
#ifndef LUMIERA_QUERY_DEFS_MANAGER_H
#define LUMIERA_QUERY_DEFS_MANAGER_H
#include "lib/p.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include <boost/scoped_ptr.hpp>
#include <boost/noncopyable.hpp>
namespace proc {
namespace mobject {
namespace session {
namespace lumiera{
namespace query {
using lib::P;
using lib::Query;
using lumiera::Query;
using boost::scoped_ptr;
namespace impl { class DefsRegistry; }
@ -126,5 +125,5 @@ namespace session {
}}} // namespace proc::mobject::session
}} // namespace lumiera::query
#endif

View file

@ -36,15 +36,15 @@
#ifndef PROC_MOBJECT_SESSION_DEFS_REGISTRY_H
#define PROC_MOBJECT_SESSION_DEFS_REGISTRY_H
#ifndef LUMIERA_QUERY_DEFS_REGISTRY_H
#define LUMIERA_QUERY_DEFS_REGISTRY_H
#include "lib/sync-classlock.hpp"
#include "lib/query.hpp"
#include "lib/p.hpp"
#include "lib/util.hpp"
#include "lib/util-foreach.hpp"
#include "lib/p.hpp"
#include "lib/sync-classlock.hpp"
#include "common/query.hpp"
#include <set>
#include <vector>
@ -54,12 +54,10 @@
#include <boost/lambda/lambda.hpp>
namespace proc {
namespace mobject {
namespace session {
namespace lumiera{
namespace query {
using lib::P;
using lib::Query;
using lib::ClassLock;
using std::tr1::weak_ptr;
@ -97,7 +95,7 @@ namespace session {
weak_ptr<TAR> objRef;
Record (const Query<TAR>& q, const P<TAR>& obj)
: degree (lib::query::countPred ("TODO")),//q)),////////////////////////////////////////////////////////////////////////////////////////////TODO
: degree (lumiera::query::countPred ("TODO")),//q)),////////////////////////////////////////////////////////////////////////////////////////////TODO
query (q),
objRef (obj)
{
@ -343,5 +341,5 @@ namespace session {
using impl::DefsRegistry;
}}} // namespace proc::mobject::session
}} // namespace lumiera::query
#endif

View file

@ -21,10 +21,10 @@
* *****************************************************/
#include "lib/query-resolver.hpp"
#include "lib/multifact-arg.hpp"
#include "common/query/query-resolver.hpp"
namespace lib {
namespace lumiera {
@ -55,14 +55,16 @@ namespace lib {
/* == dispatch to resolve typed queries == */
using factory::BuildRefcountPtr;
using lib::factory::BuildRefcountPtr;
using lib::factory::MultiFact;
/** factory used as dispatcher table
* for resolving typed queries */
typedef factory::MultiFact< Resolution(Goal const&) // nominal signature of fabrication
, Goal::QueryID // select resolution function by kind-of-Query
, BuildRefcountPtr // wrapper: manage result set by smart-ptr
> DispatcherTable; //
typedef MultiFact< Resolution(Goal const&) // nominal signature of fabrication
, Goal::QueryID // select resolution function by kind-of-Query
, BuildRefcountPtr // wrapper: manage result set by smart-ptr
> DispatcherTable; //
struct QueryDispatcher
: DispatcherTable
@ -119,4 +121,4 @@ namespace lib {
} // namespace lib
} // namespace lumiera

View file

@ -21,11 +21,11 @@
*/
#ifndef LIB_QUERY_RESOLVER_H
#define LIB_QUERY_RESOLVER_H
#ifndef LUMIERA_QUERY_RESOLVER_H
#define LUMIERA_QUERY_RESOLVER_H
#include "lib/query.hpp"
#include "lib/iter-adapter.hpp"
#include "common/query.hpp"
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
@ -35,7 +35,7 @@
using std::tr1::function;
namespace lib {
namespace lumiera {
using boost::noncopyable;
using boost::scoped_ptr;
@ -162,5 +162,5 @@ namespace lib {
}
} // namespace lib
} // namespace lumiera
#endif

View file

@ -21,10 +21,10 @@
* *****************************************************/
#include "lib/query.hpp"
#include "lib/util.hpp"
#include "lib/symbol.hpp"
#include "include/logging.h"
#include "common/query.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
@ -40,7 +40,7 @@ using util::contains;
using util::isnil;
namespace lib {
namespace lumiera {
namespace query {
namespace { // local definitions
@ -147,4 +147,4 @@ namespace lib {
} // namespace lib
} // namespace lumiera

View file

@ -205,7 +205,7 @@ namespace time {
materialiseGridPoint (Symbol gridID, int steps)
{
REQUIRE (!isnil (gridID));
PQuant grid = Quantiser::retrieve(gridID);
PQuant grid;//////////TODO = Quantiser::retrieve(gridID);
return Offset(grid->timeOf(0), grid->timeOf(steps));
}

View file

@ -27,9 +27,8 @@
#include "lib/time/quantiser.hpp"
#include "lib/time/timevalue.hpp"
#include "lib/time/display.hpp"
#include "lib/advice.hpp"
#include "common/advice.hpp"
#include "lib/util.hpp"
//#include "include/logging.h"
#include <boost/format.hpp>
#include <string>
@ -67,7 +66,7 @@ namespace meta {
using lib::time::FixedFrameQuantiser;
using std::tr1::dynamic_pointer_cast;
namespace advice = lib::advice;
namespace advice = lumiera::advice;
namespace {

View file

@ -27,7 +27,7 @@
#include "proc/asset/struct.hpp"
#include "proc/asset/procpatt.hpp"
#include "proc/streamtype.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include <string>
@ -36,7 +36,7 @@
namespace proc {
namespace asset {
using lib::Query;
using lumiera::Query;
using std::string;
class Pipe;

View file

@ -42,12 +42,12 @@
#include "proc/mobject/session/element-query.hpp"
#include "proc/mobject/session/session-query.hpp"
#include "proc/mobject/session/scope.hpp"
#include "common/configrules.hpp"
#include "common/config-rules.hpp"
#include "common/query.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "proc/asset/procpatt.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "proc/asset/struct-scheme.hpp"
@ -68,8 +68,9 @@ namespace asset {
using lib::Symbol;
using util::isnil;
using util::contains;
using lumiera::Query;
using lumiera::query::LUMIERA_ERROR_CAPABILITY_QUERY;
using lib::query::extractID;
using lumiera::query::extractID;
using proc::mobject::Session;
using proc::mobject::MObject;

View file

@ -23,22 +23,23 @@
#include "proc/asset/struct.hpp"
#include "proc/assetmanager.hpp"
#include "common/configrules.hpp"
#include "proc/config-resolver.hpp"
#include "proc/asset/struct-factory-impl.hpp"
#include "lib/util.hpp"
#include "lib/symbol.hpp"
#include "include/logging.h"
#include "common/query.hpp"
#include <boost/format.hpp>
using boost::format;
using lib::Symbol;
using lib::query::normaliseID;
using lumiera::query::normaliseID;
using lumiera::query::QueryHandler;
using lumiera::ConfigRules;
using proc::ConfigResolver;
using util::contains;
@ -101,7 +102,7 @@ namespace asset {
StructFactory::operator() (Query<STRU> const& capabilities)
{
P<STRU> res;
QueryHandler<STRU>& typeHandler = ConfigRules::instance();
QueryHandler<STRU>& typeHandler = ConfigResolver::instance();
typeHandler.resolve (res, capabilities);
if (res)

View file

@ -57,9 +57,9 @@
#ifndef ASSET_STRUCT_H
#define ASSET_STRUCT_H
#include "proc/asset.hpp"
#include "lib/query.hpp"
#include "lib/symbol.hpp"
#include "proc/asset.hpp"
#include "common/query.hpp"
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
@ -72,7 +72,7 @@ namespace asset {
using std::string;
using boost::scoped_ptr;
using lib::Query;
using lumiera::Query;
using lib::Symbol;
class Struct;

View file

@ -1,6 +1,6 @@
/*
ConfigRules - interface for rule based configuration
ConfigResolver - concrete setup for rule based configuration
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -23,18 +23,12 @@
#include "lib/error.hpp"
#include "common/configrules.hpp"
#include "proc/config-resolver.hpp"
#include "proc/mobject/session/query/fake-configrules.hpp"
namespace lumiera {
namespace query {
LUMIERA_ERROR_DEFINE (CAPABILITY_QUERY, "unresolvable capability query");
} // namespace query
namespace proc {
namespace {
@ -44,23 +38,55 @@ namespace lumiera {
/** Singleton factory instance, parametrised to actual impl. type. */
lib::SingletonSub<ConfigRules> ConfigRules::instance (typeinfo);
lib::SingletonSub<ConfigResolver> ConfigResolver::instance (typeinfo);
} // namespace proc
#include "common/query/defs-manager-impl.hpp"
/***************************************************************/
/* explicit template instantiations for querying various Types */
/***************************************************************/
#include "proc/asset/procpatt.hpp"
#include "proc/asset/pipe.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "proc/mobject/session/track.hpp"
namespace lumiera{
namespace query {
using proc::asset::Pipe;
using proc::asset::PPipe;
using proc::asset::ProcPatt;
using proc::asset::PProcPatt;
using proc::asset::Timeline;
using proc::asset::PTimeline;
using proc::asset::Sequence;
using proc::asset::PSequence;
using proc::mobject::session::Track;
using proc::mobject::session::PTrack;
template PPipe DefsManager::operator() (Query<Pipe> const&);
template PProcPatt DefsManager::operator() (Query<const ProcPatt> const&);
template PTrack DefsManager::operator() (Query<Track> const&);
template PTimeline DefsManager::operator() (Query<Timeline> const&);
template PSequence DefsManager::operator() (Query<Sequence> const&);
template bool DefsManager::define (PPipe const&, Query<Pipe> const&);
template bool DefsManager::forget (PPipe const&);
namespace query {
namespace { // local definitions: implementing a backdoor for tests
string fakeBypass;
}
void setFakeBypass(string const& q) { fakeBypass = q; }
bool isFakeBypass (string const& q) { return q == fakeBypass; }
/////////////////////////////////////////////////////////////////////////////TICKET 710
} // namespace query
} // namespace lumiera
}} // namespace lumiera::query

View file

@ -1,8 +1,9 @@
/*
CONFIGRULES.hpp - interface for rule based configuration
CONFIG-RESOLVER.hpp - concrete setup for rule based configuration
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
2012
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -21,22 +22,12 @@
*/
/** @file configrules.hpp
** Interface for accessing rule based configuration.
** By using the Query template, you can pose a query in prolog syntax and get some
** existing or newly created object fulfilling the requested predicates. The actual
** implementation is hidden behind the #instance (Singleton factory). As of 1/2008,
** it is \e planned to use an embedded YAP Prolog system at some point in the future,
** for now we use a \link MockConfigRules mock implementation \endlink employing a
** preconfigured Map.
**
** 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...
**
** @note this is rather a scrapbook and in flux... don't take this code too literal!
/** @file config-resolver.hpp
** Definition of the concrete frontend for rule based configuration within the session.
**
** @note this is placeholder code using a preliminary/mock implementation... 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
@ -46,164 +37,23 @@
*/
#ifndef LUMIERA_CONFIGRULES_H
#define LUMIERA_CONFIGRULES_H
#ifndef PROC_CONFIG_RESOLVER
#define PROC_CONFIG_RESOLVER
#include "lib/p.hpp"
#include "lib/query.hpp"
#include "lib/symbol.hpp"
#include "lib/meta/generator.hpp"
#include "common/query.hpp"
#include "common/config-rules.hpp"
#include "lib/singleton-subclass.hpp"
//TODO: is it sensible to bring in the types explicitly here? (it's not necessary, but may be convenient...)
// types for explicit specialisations....
#include "proc/mobject/session/track.hpp"
#include "proc/asset/procpatt.hpp"
#include "proc/asset/pipe.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include <string>
namespace lumiera { ///////TODO: shouldn't that be namespace lib? or proc?
using std::string;
using lib::P;
namespace query {
// The intention is to support the following style of Prolog code
//
// resolve(O, Cap) :- find(O), capabilities(Cap).
// resolve(O, Cap) :- make(O), capabilities(Cap).
// capabilities(Q) :- call(Q).
//
// stream(T, mpeg) :- type(T, track), type(P, pipe), resolve(P, stream(P,mpeg)), placed_to(P, T).
//
// The type guard is inserted automatically, while the predicate implementations for
// find/1, make/1, stream/2, and placed_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 pipe object with stream-type=mpeg and associate the track with this Pipe. The
// predicate "stream(P,mpeg)" needs to be implemented (natively) for the pipe object.
class Resolver
{
};
using lib::Symbol;
using lib::Literal;
using lib::Query;
/** placeholder definition for later.
* @todo intention is to integrate with lib::Symbol
*/
#define SYMBOL uint
template
< SYMBOL SYM, // Predicate symbol
typename SIG = bool(string) // Signature
>
class Pred
{ };
/**
* the "back side" interface towards the classes participating
* in the configuration system (the config system will be
* delivering instances of these classes for a given query).
* This one currently is just brainstorming. The idea is that
* a participating class would provide such and TypeHandler
* implementing the predicates which make sense for this special
* type of object. Registering such a TypeHandler should create
* the necessary handler functions to be installed into
* the Prolog system.
* @todo it can't be done exactly this way, but I leave it in
* as a reminder for later, to show the intention
*/
template<class TY>
class TypeHandler
{
static const TY NIL;
template<SYMBOL SYM, typename SIG>
TY find (Pred<SYM,SIG> capability);
template<SYMBOL SYM, typename SIG>
TY make (Pred<SYM,SIG> capability, TY& refObj =NIL);
};
/**
* the "front side" interface: the Proc-Layer code can
* use this QueryHandler to retrieve instances of the
* type TY fulfilling the given Query. To start with,
* we use a mock implementation.
* (this code works and is already used 2/2008)
* @see lumiera::query::LookupPreconfigured
* @see lumiera::query::MockTable
*/
template<class TY>
class QueryHandler
{
protected:
virtual ~QueryHandler() { }
public:
/** try to find or create an object of type TY
* fulfilling the given query.
* @param solution object fulfilling the query. Will be bound or
* unified (in case it's already bound) with the first solution.
* @query any goals to be fulfilled by the solution.
* @return false if resolution failed. In this case, solution ptr is empty.
*/
virtual bool resolve (P<TY>& solution, const Query<TY>& q) = 0;
};
// 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 P<Pipe> but a Placement<Track>, using the appropriate factory.
// Of course then the definitions need to be split up in separate headers.
/**
* 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 specialisations
* given alongside with the types. For now it just serves to generate
* the necessary resolve(Query<TY>) virtual functions (implemented
* by MockConfigRules)
*/
template<typename TYPES>
class ConfigRules
: public lib::meta::InstantiateForEach<TYPES, QueryHandler>
{
protected:
ConfigRules () {}
virtual ~ConfigRules() {}
public:
// TODO: find out what operations we need to support here for the »real solution« (using Prolog)
};
LUMIERA_ERROR_DECLARE (CAPABILITY_QUERY); ///< unresolvable capability query.
} // namespace query
namespace proc {
@ -226,29 +76,15 @@ namespace lumiera { ///////TODO: shouldn't that be namespace lib? or proc?
* user-visible Interface to the ConfigRules subsystem.
* Configured as Singleton (with hidden Implementation class)
*/
class ConfigRules
: public query::ConfigRules<InterfaceTypes>
class ConfigResolver
: public lumiera::query::ConfigRules<InterfaceTypes>
{
public:
static lib::SingletonSub<ConfigRules> instance;
static lib::SingletonSub<ConfigResolver> instance;
};
namespace query {
/** backdoor for tests: the next config query with this query string
* will magically succeed with every candidate object provided. This
* is currently necessary to get objects into the defaults manager,
* 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
} // namespace lumiera
} // namespace proc
#endif

View file

@ -38,7 +38,7 @@
#include "proc/control/stypemanager.hpp"
//#include "lib/query.hpp"
//#include "common/query.hpp"
//#include "lib/util.hpp"
//#include "lib/p.hpp"

View file

@ -25,7 +25,7 @@
#define MOBJECT_BUILDER_OPERATIONPOINT_H
//#include "proc/engine/procnode.hpp" /////TODO can we get rid of this header here?
#include "lib/query.hpp"
//#include "common/query.hpp"
#include <boost/scoped_ptr.hpp>
#include <vector>

View file

@ -43,16 +43,16 @@
#include "proc/mobject/placement-ref.hpp"
#include "proc/mobject/output-designation.hpp"
#include "proc/mobject/output-mapping.hpp"
#include "common/configrules.hpp"
#include "proc/config-resolver.hpp"
#include <boost/functional/hash.hpp>
#include <cstdlib>
using lumiera::query::QueryHandler;
using lumiera::ConfigRules;
using lumiera::Symbol;
using lib::query::removeTerm;
using lib::query::extractID;
using lumiera::query::QueryHandler;
using lumiera::query::removeTerm;
using lumiera::query::extractID;
using proc::ConfigResolver;
namespace proc {
namespace mobject {
@ -168,7 +168,7 @@ namespace mobject {
resolveQuery (Query<asset::Pipe> const& query4pipe)
{
PPipe res;
QueryHandler<asset::Pipe>& typeHandler = ConfigRules::instance();
QueryHandler<asset::Pipe>& typeHandler = ConfigResolver::instance();
typeHandler.resolve (res, query4pipe);
HashVal resulting_targetPipeID (res? (HashVal)res->getID() : 0 );
return resulting_targetPipeID;

View file

@ -52,11 +52,11 @@
#ifndef PROC_MOBJECT_OUTPUT_MAPPING_H
#define PROC_MOBJECT_OUTPUT_MAPPING_H
#include "lib/error.hpp"
#include "lib/util.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/bool-checkable.hpp"
#include "lib/error.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp"
#include "common/query.hpp"
#include <boost/operators.hpp>
#include <map>
@ -96,7 +96,7 @@ namespace mobject {
}//(End) type rebinding helper
namespace error = lumiera::error;
using lib::Query;
using lumiera::Query;
using asset::HashVal;
@ -213,7 +213,7 @@ namespace mobject {
* This operation is invoked when client code accesses
* the result of an OutputMapping query.
* @return result of invoking the configured \c DEF::output functor
* @throw error::Logic when resoving an \em unconnected mapping
* @throw error::Logic when resolving an \em unconnected mapping
*/
operator Target()
{

View file

@ -51,7 +51,7 @@
#include "proc/mobject/placement.hpp"
#include "proc/mobject/mobject-ref.hpp"
#include "proc/mobject/session/defs-manager.hpp" ////////////////////////////TICKET #643 forward declare this?
#include "common/query/defs-manager.hpp" ////////////////////////////TICKET #643 forward declare this?
#include "lib/ref-array.hpp"
#include "lib/singleton.hpp"
#include "lib/symbol.hpp"
@ -107,7 +107,7 @@ namespace mobject {
: boost::noncopyable
{
protected:
typedef session::DefsManager& DefaultsAccess;
typedef lumiera::query::DefsManager& DefaultsAccess;
typedef session::ElementQuery& ElementsAccess;
typedef lib::RefArray<asset::PTimeline>& TimelineAccess;
typedef lib::RefArray<asset::PSequence>& SequenceAccess;

View file

@ -148,7 +148,7 @@ namespace session {
LocatingPin::LocatingSolution::getPipe()
{
TODO ("implement Placement LocatingSolution");
return asset::Pipe::query (lib::Query<asset::Pipe>("pipe(master)")); // yet another idiotic dummy
return asset::Pipe::query (lumiera::Query<asset::Pipe>("pipe(master)")); // yet another idiotic dummy
}

View file

@ -30,6 +30,9 @@
#include "proc/mobject/session/binding.hpp"
#include "proc/asset/clip.hpp"
#include "proc/asset/effect.hpp"
#include "common/query/defs-manager.hpp"
using lumiera::query::DefsManager;
namespace proc {
namespace mobject {

View file

@ -29,6 +29,10 @@
#include "lib/symbol.hpp"
namespace lumiera {
namespace query {
class DefsManager;
}}
namespace proc {
namespace asset {
@ -52,7 +56,6 @@ namespace session {
class Label;
class Binding;
class DefsManager;
class MObjectFactory
@ -64,7 +67,7 @@ namespace session {
public:
Placement<Root> operator() (DefsManager&);
Placement<Root> operator() (lumiera::query::DefsManager&);
Placement<Clip> operator() (asset::Clip const&, asset::Media const&);
Placement<Clip> operator() (asset::Clip const&, vector<asset::Media const*>);
Placement<Track> operator() (asset::EntryID<Track> const&);

View file

@ -39,10 +39,10 @@ namespace session {
using boost::scoped_ptr;
using lib::Goal;
using lib::Query;
using lib::Resolution;
using lib::getResultTypeID;
using lumiera::Goal;
using lumiera::Query;
using lumiera::Resolution;
using lumiera::getResultTypeID;
typedef PlacementIndex::ID PID;
@ -194,7 +194,7 @@ namespace session {
* there is a smart-ptr managing this ResultSet.
*/
class ResultSet
: public lib::Resolution
: public lumiera::Resolution
{
ContentFilter acceptable_;
ExplorerBuilder buildExploartion_;
@ -325,7 +325,7 @@ namespace session {
bool
PlacementIndexQueryResolver::canHandleQuery(QID qID) const
{
return qID.kind == Goal::DISCOVERY
return qID.kind == Goal::DISCOVERY
&&( qID.type == getResultTypeID<Placement<MObject> >()
||qID.type == getResultTypeID<Placement<Clip> >()
||qID.type == getResultTypeID<Placement<Effect> >()

View file

@ -59,7 +59,7 @@
#include "proc/mobject/session/placement-index.hpp"
#include "proc/mobject/session/scope-query.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include <tr1/functional>
@ -69,6 +69,7 @@ namespace mobject {
namespace session {
using std::tr1::function;
using lumiera::Goal;
typedef PlacementIndex& IndexLink(void);
@ -87,7 +88,7 @@ namespace session {
* * more generally, any ScopeQuery with these properties, in some variations
*/
class PlacementIndexQueryResolver
: public lib::QueryResolver
: public lumiera::QueryResolver
{
function<IndexLink> _getIndex;
@ -106,7 +107,7 @@ namespace session {
void defineHandling();
template<typename MO>
lib::Resolution* resolutionFunction (Goal const& goal);
lumiera::Resolution* resolutionFunction (Goal const& goal);
public:

View file

@ -27,7 +27,7 @@
#include "proc/mobject/session/track.hpp"
#include "proc/asset/procpatt.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "include/logging.h"
@ -53,7 +53,7 @@ namespace session {
using asset::PProcPatt;
// using lumiera::query::extractID;
using lib::query::removeTerm;
using lumiera::query::removeTerm;
namespace {

View file

@ -41,8 +41,9 @@
#define MOBJECT_SESSION_QUERY_FAKECONFIGRULES_H
#include "proc/mobject/session.hpp"
#include "common/configrules.hpp"
#include "proc/config-resolver.hpp"
#include "lib/util.hpp"
#include "lib/p.hpp"
#include <boost/scoped_ptr.hpp>
#include <boost/any.hpp>
@ -63,11 +64,12 @@ namespace session {
using asset::PProcPatt;
using proc::mobject::Session;
using lib::meta::InstantiateChained;
using lib::P;
using lib::Query;
using lib::query::removeTerm; //////////////TODO better use Query::Builder
using lib::query::extractID; ///////////////TODO dto
using lumiera::query::isFakeBypass; /////////TODO placeholder until there is a real resolution engine
using lumiera::Query;
using lumiera::query::removeTerm; //////////////TODO better use Query::Builder
using lumiera::query::extractID; ///////////////TODO dto
using lumiera::query::isFakeBypass; /////////TODO placeholder until there is a real resolution engine
using util::contains;
using util::isnil;
@ -106,7 +108,8 @@ namespace session {
* the actual table holding preconfigured answers
* packaged as boost::any objects.
*/
class MockTable : public lumiera::ConfigRules
class MockTable
: public proc::ConfigResolver
{
typedef std::map<string,any> Tab;
typedef boost::scoped_ptr<Tab> PTab;
@ -261,7 +264,7 @@ namespace session {
* values for some types of interest for testing and debugging.
*/
class MockConfigRules
: public InstantiateChained < lumiera::InterfaceTypes
: public InstantiateChained < proc::InterfaceTypes
, LookupPreconfigured // building block used for each of the types
, MockTable // for implementing the base class (interface)
>

View file

@ -22,8 +22,9 @@
#include "proc/mobject/session/root.hpp"
#include "proc/mobject/session/defs-manager.hpp"
#include "common/query/defs-manager.hpp"
using lumiera::query::DefsManager;
namespace proc {
namespace mobject {

View file

@ -28,11 +28,15 @@
#include "proc/mobject/builder/buildertool.hpp"
namespace lumiera {
namespace query {
class DefsManager;
}}
namespace proc {
namespace mobject {
namespace session {
class DefsManager;
/**
@ -50,7 +54,7 @@ namespace session {
*/
class Root : public Meta
{
DefsManager& defaults_;
lumiera::query::DefsManager& defaults_;
///////////TODO: timespan fields here or already in class Meta??
///////////TODO: any idea about the purpose of root's "timespan"?? ///////TICKET #448
@ -64,7 +68,7 @@ namespace session {
virtual bool isValid() const;
public:
Root (DefsManager&);
Root (lumiera::query::DefsManager&);
DEFINE_PROCESSABLE_BY (builder::BuilderTool);

View file

@ -97,7 +97,7 @@ namespace session {
friend class lib::singleton::StaticCreate<ScopeLocator>;
private:
lib::QueryResolver const& theResolver();
lumiera::QueryResolver const& theResolver();
};

View file

@ -43,7 +43,7 @@
#include "proc/mobject/placement.hpp"
#include "lib/query-resolver.hpp"
#include "common/query/query-resolver.hpp"
#include <tr1/functional>
@ -56,8 +56,8 @@ namespace session {
using std::tr1::function;
using std::tr1::placeholders::_1;
using lib::Goal;
using lib::Query;
using lumiera::Goal;
using lumiera::Query;

View file

@ -44,6 +44,7 @@
#include "proc/mobject/session/session-service-explore-scope.hpp"
#include "proc/mobject/mobject.hpp"
#include "lib/iter-source.hpp" ////////////////////TICKET #493 : using the IterSource adapters here
#include "common/query/query-resolver.hpp"
#include <vector>
@ -119,7 +120,7 @@ namespace session {
* of contents discovery queries to the PlacementIndex
* managed within the session
*/
lib::QueryResolver const&
lumiera::QueryResolver const&
ScopeLocator::theResolver()
{
return SessionServiceExploreScope::getResolver();

View file

@ -38,13 +38,13 @@
*/
#include "lib/error.hpp"
#include "proc/mobject/session.hpp"
#include "proc/mobject/session/sess-manager-impl.hpp"
#include "proc/mobject/session/defs-manager.hpp"
#include "proc/mobject/session/lifecycle-advisor.hpp"
#include "proc/asset/timeline.hpp"
#include "lib/error.hpp"
#include "lib/query.hpp"
#include "common/query/defs-manager.hpp"
#include "common/query.hpp"
using boost::scoped_ptr;
@ -126,7 +126,7 @@ namespace session {
REQUIRE (0 == session_->timelines.size(), "injecting default timeline, but session isn't pristine");
// issue a default query to retrieve or create a Timeline and a default Sequence
asset::PTimeline initialTimeline = session_->defaults (lib::Query<asset::Timeline> ());
asset::PTimeline initialTimeline = session_->defaults (lumiera::Query<asset::Timeline> ());
// these got registered automatically
ENSURE (1 == session_->timelines.size());

View file

@ -73,8 +73,8 @@
#include "lib/element-tracker.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "proc/mobject/session/defs-manager.hpp"
#include "proc/mobject/session/element-query.hpp"
#include "common/query/defs-manager.hpp"
@ -96,8 +96,8 @@ namespace session {
struct SessionInterfaceModules
: boost::noncopyable
{
DefsManager defaultsManager_;
ElementQuery elementQueryAPI_;
lumiera::query::DefsManager defaultsManager_;
mobject::session::ElementQuery elementQueryAPI_;
TimelineTracker timelineRegistry_;
SequenceTracker sequenceRegistry_;

View file

@ -47,7 +47,7 @@
#define MOBJECT_SESSION_SESSION_SERVICE_EXPLORE_SCOPE_H
#include "proc/mobject/placement.hpp"
#include "lib/query-resolver.hpp"
#include "common/query/query-resolver.hpp"
@ -68,7 +68,7 @@ namespace session {
*/
struct SessionServiceExploreScope
{
static lib::QueryResolver const& getResolver();
static lumiera::QueryResolver const& getResolver();
static PlacementMO& getScope (PlacementMO const&);
static PlacementMO& getScope (PlacementMO::ID const&);

View file

@ -32,9 +32,9 @@
#include "proc/mobject/session.hpp"
#include "proc/mobject/session/defs-manager.hpp"
#include "proc/mobject/session/session-impl.hpp"
#include "proc/mobject/session/sess-manager-impl.hpp"
//#include "common/query/defs-manager.hpp"
#include "lib/symbol.hpp"
#include "lib/singleton.hpp"

View file

@ -27,6 +27,7 @@
#include "proc/mobject/session/scope-query.hpp"
#include "proc/mobject/placement.hpp"
#include "common/query/query-resolver.hpp"
#include <tr1/functional>
@ -37,7 +38,7 @@ namespace session {
using std::tr1::function;
using lib::QueryResolver;
using lumiera::QueryResolver;
/**

View file

@ -85,7 +85,7 @@
#include "proc/mobject/builder/model-port-registry.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "lib/util.hpp"
//#include "lib/symbol.hpp"
@ -125,7 +125,7 @@ namespace play {
using mobject::ModelPort;
using mobject::builder::ModelPortRegistry;
using util::contains;
using lib::Query;
using lumiera::Query;
// using lib::ScopedCollection;
// using lib::Literal;
using lib::eachEntry;

View file

@ -36,7 +36,7 @@
#include "lib/symbol.hpp"
#include "lib/query.hpp"
//#include "common/query.hpp"
#include "proc/asset/entry-id.hpp"
#include <boost/noncopyable.hpp>

View file

@ -27,10 +27,10 @@
#include "proc/asset/category.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "proc/assetmanager.hpp"
#include "proc/mobject/session.hpp"
#include "proc/asset/asset-diagnostics.hpp"
#include "common/query.hpp"
#include <boost/format.hpp>
#include <iostream>
@ -47,8 +47,8 @@ namespace asset {
namespace test {
using mobject::Session;
using lib::Query;
using lib::query::normaliseID;
using lumiera::Query;
using lumiera::query::normaliseID;

View file

@ -91,7 +91,7 @@ namespace test {
EngineService& engine = EngineService::instance();
EngineDiagnostics monitor(engine);
PID pipe = Pipe::query(lib::Query<Pipe> ("id(dummy)"));
PID pipe = Pipe::query(lumiera::Query<Pipe> ("id(dummy)"));
ModelPort port(pipe);
OutputSlot& oSlot = DiagnosticOutputSlot::build();

View file

@ -26,7 +26,7 @@
#include "proc/mobject/builder/fixture-change-detector.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "lib/util.hpp"
@ -43,7 +43,7 @@ namespace test {
using asset::Struct;
using asset::Timeline;
using asset::PTimeline;
using lib::Query;
using lumiera::Query;
//
typedef asset::ID<Pipe> PID;
typedef asset::ID<Struct> TID;

View file

@ -26,7 +26,7 @@
#include "proc/mobject/builder/model-port-registry.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "lib/util.hpp"
@ -43,7 +43,7 @@ namespace test {
using asset::Struct;
using asset::Timeline;
using asset::PTimeline;
using lib::Query;
using lumiera::Query;
typedef asset::ID<Pipe> PID;
typedef asset::ID<Struct> TID;

View file

@ -26,7 +26,7 @@
#include "proc/mobject/builder/fixture-change-detector.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "lib/util.hpp"
@ -43,7 +43,7 @@ namespace test {
using asset::Struct;
using asset::Timeline;
using asset::PTimeline;
using lib::Query;
using lumiera::Query;
//
typedef asset::ID<Pipe> PID;
typedef asset::ID<Struct> TID;

View file

@ -27,10 +27,11 @@
#include "proc/asset.hpp"
#include "proc/asset/pipe.hpp"
#include "proc/asset/struct.hpp"
#include "common/configrules.hpp"
#include "proc/config-resolver.hpp"
#include "proc/assetmanager.hpp"
#include "proc/mobject/session.hpp"
#include "proc/streamtype.hpp"
#include "common/query.hpp"
#include <boost/format.hpp>
@ -45,16 +46,17 @@ namespace session {
namespace test {
using lib::Symbol;
using lib::Query;
using lib::query::normaliseID;
using asset::Asset;
using asset::AssetManager;
using asset::Pipe;
using asset::PPipe;
using asset::Struct;
using lumiera::ConfigRules;
using lumiera::Query;
using lumiera::query::QueryHandler;
using lumiera::query::normaliseID;
using proc::ConfigResolver;
@ -136,7 +138,7 @@ lumiera::query::setFakeBypass("stream("+sID+")"); //////////////////////////////
Query<Pipe> query_for_streamID ("stream("+sID+")");
// issue a ConfigQuery directly, without involving the DefaultsManager
QueryHandler<Pipe>& typeHandler = ConfigRules::instance();
QueryHandler<Pipe>& typeHandler = ConfigResolver::instance();
PPipe pipe1;
typeHandler.resolve (pipe1, query_for_streamID);
CHECK (pipe1);

View file

@ -23,8 +23,8 @@
#include "lib/test/run.hpp"
#include "lib/symbol.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp"
#include "common/query.hpp"
#include "proc/asset.hpp"
#include "proc/asset/pipe.hpp"
@ -54,8 +54,8 @@ namespace test {
using asset::Pipe;
using asset::PPipe;
using asset::Struct;
using lib::Query;
using lib::query::normaliseID;
using lumiera::Query;
using lumiera::query::normaliseID;
/** shortcut: run just a query

View file

@ -24,8 +24,8 @@
#include "lib/test/run.hpp"
#include "lib/util.hpp"
#include "proc/mobject/session/defs-registry.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "common/query/defs-registry.hpp"
#include "lib/p.hpp"
#include "../lib/query/querydiagnostics.hpp"
@ -34,8 +34,6 @@
#include <boost/format.hpp>
#include <map>
using lib::Query;
using lib::query::test::garbage_query;
using util::isnil;
using lib::P;
@ -47,9 +45,8 @@ using std::map;
namespace proc {
namespace mobject {
namespace session {
namespace lumiera {
namespace query {
namespace test {
format typePatt ("Dummy<%2i>");
@ -299,4 +296,4 @@ namespace test {
}}}} // namespace proc::mobject::session::test
}}} // namespace lumiera::query::test

View file

@ -26,7 +26,7 @@
#include "proc/mobject/session/session-service-explore-scope.hpp"
#include "proc/mobject/session/placement-index-query-resolver.hpp"
#include "proc/mobject/session/test-scopes.hpp"
#include "lib/query-resolver.hpp"
#include "common/query/query-resolver.hpp"
#include "lib/util.hpp"
#include <iostream>
@ -39,7 +39,7 @@ namespace mobject {
namespace session {
namespace test {
using lib::QueryResolver;
using lumiera::QueryResolver;
using session::PathQuery;
using session::ContentsQuery;
using util::isSameObject;

View file

@ -23,15 +23,16 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/query-resolver.hpp"
#include "lib/singleton.hpp"
#include "common/query/query-resolver.hpp"
#include <iostream>
#include <string>
namespace lib {
namespace lumiera {
namespace test{
using lib::test::showSizeof;
@ -221,4 +222,4 @@ namespace test{
LAUNCHER (QueryResolver_test, "unit session");
}} // namespace lib::test
}} // namespace lumiera::test

View file

@ -29,7 +29,8 @@
#include "proc/mobject/session.hpp"
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "lib/p.hpp"
@ -84,7 +85,8 @@ namespace test {
using lib::Query;
using lib::P;
using lumiera::Query;
using asset::Timeline;
using asset::PTimeline;
using asset::AssetManager;

View file

@ -31,7 +31,7 @@
#include "proc/mobject/session/testclip.hpp"
#include "proc/mobject/mobject-ref.hpp"
#include "proc/mobject/placement.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include <tr1/functional>
#include <iostream>
@ -58,7 +58,7 @@ namespace test {
using asset::PSequence;
using asset::Sequence;
using lib::Query;
using lumiera::Query;
typedef MORef<session::Clip> RClip;
typedef PlacementMO::ID PID;

View file

@ -30,7 +30,7 @@
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "lib/util.hpp"
#include <iostream>
@ -55,7 +55,7 @@ namespace test {
using asset::PSequence;
using asset::Pipe;
using lib::Query;
using lumiera::Query;
/********************************************************************************

View file

@ -41,9 +41,9 @@
#include "lib/time/timevalue.hpp"
#include "lib/scoped-ptrvect.hpp"
#include "lib/iter-source.hpp"
#include "lib/advice.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include "common/advice.hpp"
#include "proc/engine/testframe.hpp"
//#include "lib/sync.hpp"
@ -80,7 +80,7 @@ namespace play {
getTestTimeGrid()
{
Symbol gridID("DiagnosticOutputSlot-buffer-grid");
lib::advice::Request<PGrid> query4grid(gridID) ;
lumiera::advice::Request<PGrid> query4grid(gridID) ;
PGrid testGrid25 = query4grid.getAdvice();
if (!testGrid25)

View file

@ -22,7 +22,7 @@
#include "lib/test/run.hpp"
#include "lib/advice.hpp"
#include "common/advice.hpp"
#include <cstdlib>
@ -30,7 +30,7 @@ using std::rand;
namespace lib {
namespace lumiera {
namespace advice {
namespace test {
@ -264,4 +264,4 @@ namespace test {
LAUNCHER (AdviceBasics_test, "unit common");
}}} // namespace lib::advice::test
}}} // namespace lumiera::advice::test

View file

@ -24,18 +24,19 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/advice.hpp"
#include "lib/time/timevalue.hpp"
#include "common/advice.hpp"
#include <iostream>
using lib::time::Time;
using std::cout;
using std::endl;
namespace lib {
namespace advice{
namespace lumiera {
namespace advice {
namespace test {
namespace {
@ -127,11 +128,11 @@ namespace test {
b2.addPredicate("cat3(zzz)");
CHECK (b1 != b2);
b1.addTypeGuard<time::Time>();
b1.addTypeGuard<Time>();
CHECK (b1 != b2);
b1.addPredicate(" cat3( zzz ) ");
CHECK (b1 != b2);
b2.addTypeGuard<time::Time>();
b2.addTypeGuard<Time>();
CHECK (b1 == b2);
cout << "b2==" << b2 << endl;
@ -214,4 +215,4 @@ namespace test {
LAUNCHER (AdviceBindingPattern_test, "unit common");
}}} // namespace lib::advice::test
}}} // namespace lumiera::advice::test

View file

@ -24,7 +24,7 @@
#include "lib/test/run.hpp"
//#include "lib/test/test-helper.hpp"
#include "lib/advice.hpp"
#include "common/advice.hpp"
//#include "lib/p.hpp"
//#include "proc/assetmanager.hpp"
//#include "proc/asset/inventory.hpp"
@ -52,7 +52,7 @@
namespace lib {
namespace lumiera {
namespace advice {
namespace test {
@ -129,4 +129,4 @@ namespace test {
LAUNCHER (AdviceConfiguration_test, "unit common");
}}} // namespace lib::advice::test
}}} // namespace lumiera::advice::test

View file

@ -22,7 +22,7 @@
#include "lib/test/run.hpp"
#include "lib/advice/index.hpp"
#include "common/advice/index.hpp"
#include <vector>
@ -30,7 +30,7 @@ using lib::Literal;
namespace lib {
namespace lumiera {
namespace advice {
namespace test {
@ -430,4 +430,4 @@ namespace test {
LAUNCHER (AdviceIndex_test, "function common");
}}} // namespace lib::advice::test
}}} // namespace lumiera::advice::test

View file

@ -24,7 +24,6 @@
#include "lib/test/run.hpp"
//#include "lib/test/test-helper.hpp"
#include "lib/advice.hpp"
//#include "lib/p.hpp"
//#include "proc/assetmanager.hpp"
//#include "proc/asset/inventory.hpp"
@ -33,6 +32,7 @@
//#include "lib/meta/trait-special.hpp"
//#include "lib/util-foreach.hpp"
//#include "lib/symbol.hpp"
#include "common/advice.hpp"
//#include <iostream>
//#include <string>
@ -52,7 +52,7 @@
namespace lib {
namespace lumiera {
namespace advice {
namespace test {
@ -131,4 +131,4 @@ namespace test {
LAUNCHER (AdviceMultiplicity_test, "function common");
}}} // namespace lib::advice::test
}}} // namespace lumiera::advice::test

View file

@ -24,7 +24,8 @@
#include "lib/test/run.hpp"
//#include "lib/test/test-helper.hpp"
#include "lib/advice.hpp"
#include "common/advice.hpp"
//#include "lib/p.hpp"
//#include "proc/assetmanager.hpp"
//#include "proc/asset/inventory.hpp"
@ -52,7 +53,7 @@
namespace lib {
namespace lumiera {
namespace advice {
namespace test {
@ -112,4 +113,4 @@ namespace test {
LAUNCHER (AdviceSituations_test, "function common");
}}} // namespace lib::advice::test
}}} // namespace lumiera::advice::test

View file

@ -26,13 +26,13 @@
#include "lib/util-foreach.hpp"
#include "lib/cmdline.hpp"
#include "lib/query.hpp"
#include "common/query.hpp"
#include "query/querydiagnostics.hpp"
#include <tr1/functional>
#include <iostream>
using lib::Query;
using lumiera::Query;
using lib::Cmdline;
using util::isnil;
using util::contains;
@ -46,7 +46,7 @@ using std::endl;
namespace lib {
namespace lumiera {
namespace query {
namespace test{

View file

@ -21,8 +21,8 @@
*/
#ifndef LIB_QUERY_TEST_QUERYDIAGNOSTICS_H
#define LIB_QUERY_TEST_QUERYDIAGNOSTICS_H
#ifndef LUMIERA_QUERY_TEST_QUERYDIAGNOSTICS_H
#define LUMIERA_QUERY_TEST_QUERYDIAGNOSTICS_H
#include "lib/format-string.hpp"
@ -33,7 +33,7 @@ using std::rand;
namespace lib {
namespace lumiera {
namespace query{
namespace test {
@ -72,5 +72,5 @@ namespace test {
}}} // namespace lib::query::test
}}} // namespace lumiera::query::test
#endif

View file

@ -26,11 +26,11 @@
#include "common/subsys.hpp"
#include "common/subsystem-runner.hpp"
#include "common/option.hpp"
#include "common/query.hpp"
#include "lib/symbol.hpp"
#include "backend/thread-wrapper.hpp"
#include "lib/error.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp"
#include "lib/sync.hpp"
@ -43,7 +43,7 @@ using util::isnil;
using util::cStr;
using test::Test;
using lib::Literal;
using lib::query::extractID;
using lumiera::query::extractID;
using backend::Thread;
@ -52,7 +52,7 @@ namespace test {
namespace { // private test classes and data...
using lib::query::extractID;
using lumiera::query::extractID;
/** limit for the randomly selected duration of
* subsystem's running phase (milliseconds) */

View file

@ -514,9 +514,9 @@ ColorPalette
SiteUrl</pre>
</div>
<div title="Advice" modifier="Ichthyostega" modified="201005290215" created="200910311755" tags="Concepts def spec img" changecount="31">
<div title="Advice" modifier="Ichthyostega" modified="201211300554" created="200910311755" tags="Concepts def spec img" changecount="32">
<pre>//pattern of collaboration for loosely coupled entities, to be used for various purposes within Proc...//
Expecting Advice and giving Advice &amp;mdash; this collaboration ranges somewhere between messaging and dynamic properties, but cross-cutting the primary, often hierarchical relation of dependencies. Always happening at a certain //point of advice,// which creates a distinct, static nature different of being just a convention, on the other hand, Advice is deliberately kept optional and received synchronously, albeit possibly within an continuation.
Expecting Advice and giving Advice &amp;mdash; this collaboration ranges somewhere between messaging and dynamic properties, but cross-cutting the primary, often hierarchical relation of dependencies. Always happening at a certain //point of advice,// this exchange of data gains a distinct, static nature -- it is more than just a convention or a protocol. On the other hand, Advice is deliberately kept optional and received synchronously (albeit possibly within an continuation), this way allowing for loose coupling. This indirect, cross-cutting nature allows to build integration points into library facilities, without enforcing a strong dependency link.
!Specification
''Definition'': Advice is an optional, mediated collaboration between entities taking on the roles of advisor and advised, thereby passing a custom piece of advice data, managed by the advice support system. The possibility of advice is created by both of the collaborators entering the system, where the advised entity exposes a point of advice, while the advising entity provides an actual advice value.
@ -540,7 +540,7 @@ In a more elaborate scheme, the advised entity could provide a signal to be invo
&amp;rarr; AdviceImplementation
</pre>
</div>
<div title="AdviceImplementation" modifier="Ichthyostega" modified="201101100014" created="201004100056" tags="impl draft img" changecount="59">
<div title="AdviceImplementation" modifier="Ichthyostega" modified="201211300647" created="201004100056" tags="impl draft img" changecount="61">
<pre>[&lt;img[Advice solution|uml/fig141573.png]]
@ -549,7 +549,7 @@ In a more elaborate scheme, the advised entity could provide a signal to be invo
The advice system is //templated on the advice type// &amp;mdash; so basically any collaboration is limited to a distinct advice type. But currently (as of 5/2010), this typed context is kept on the interface level, while the implementation is built on top of a single lookup table (which might create contention problems in the future and thus may be changed without further notice). The advice system is a system wide singleton service, but it is never addressed directly by the participants. Rather, instances of ~AdviceProvision and ~AdviceRequest act as point of access. But these aren't completely symmetric; while the ~AdviceRequest is owned by the advised entity, the ~AdviceProvision is a value object, a uniform holder used to introduce new advice into the system. ~AdviceProvision is copied into an internal buffer and managed by the advice system, as is the actual advice item, which is copied alongside.
In order to find matches and provide advice solutions, the advice system maintains an index data structure called ''~Binding-Index''. The actual binding predicates are represented by value objects stored within this index table. The matching process is triggered whenever a new possibility for an advice solution enters the system, which could be a new request, a new provision or a change in the specified bindings. A successful match causes a pointer to be set within the ~AdviceRequest, pointing to the ~AdviceProvision acting as solution. Thus, when a solution exists, the advised entity can access the advice value object by dereferencing this pointer. A new advice solution just results in setting a different pointer, which is atomic and doesn't need to be protected by locking. But note, omitting the locking means there is no memory barrier; thus the advised entity might not see any changed advice solution, until the corresponding thread(s) refresh their CPU cache. This might or might not be acceptable, depending on the context, and thus is configurable as policy. Similarly, the handling of default advice is configurable. Usually, advice is a default constructible value object. In this case, when there isn't any advice solution (yet), a pseudo solution holding the default constructed advice value is used to satisfy any advice access by the client (advised entity). The same can be used when the actual ~AdviceProvision gets //retracted.// As an alternative, when this default solution approach doesn't work, we can provide a policy either to throw or to wait blocking &amp;mdash; but this alternative policy is similarly implemented with an //null object// (a placeholder ~AdviceProvision). Anyway, this implementation technique causes the advice system to collect some advice provisions, bindings and advice objects over time. It should use a pooling custom allocator in the final version. As the number of advisors is expected to be rather small, the storage occupied by these elements, which is effectively blocked until application exit, isn't considered a problem.
In order to find matches and provide advice solutions, the advice system maintains an index data structure called ''~Binding-Index''. The actual binding predicates are represented by value objects stored within this index table. The matching process is triggered whenever a new possibility for an advice solution enters the system, which could be a new request, a new provision or a change in the specified bindings. A successful match causes a pointer to be set within the ~AdviceRequest, pointing to the ~AdviceProvision acting as solution. Thus, when a solution exists, the advised entity can access the advice value object by dereferencing this pointer. A new advice solution just results in setting a different pointer, which is atomic and doesn't need to be protected by locking. But note, omitting the locking means there is no memory barrier; thus the advised entity might not see any changed advice solution, until the corresponding thread(s) refresh their CPU cache. This might or might not be acceptable, depending on the context, and thus is configurable as policy. Similarly, the handling of default advice is configurable. Usually, advice is a default constructible value object. In this case, when there isn't any advice solution (yet), a pseudo solution holding the default constructed advice value is used to satisfy any advice access by the client (advised entity). The same can be used when the actual ~AdviceProvision gets //retracted.// As an alternative, when this default solution approach doesn't work, we can provide a policy either to throw or to wait blocking &amp;mdash; but this alternative policy is similarly implemented with a //null object// (a placeholder ~AdviceProvision). Anyway, this implementation technique causes the advice system to collect some advice provisions, bindings and advice objects over time. It should use a pooling custom allocator in the final version. As the number of advisors is expected to be rather small, the storage occupied by these elements, which is effectively blocked until application exit, isn't considered a problem.
!organising the advice solution
This is the tricky part of the whole advice system implementation. A naive implementation will quickly degenerate in performance, as costs are of order ~AdviceProvisions * ~AdviceRequests * (average number of binding terms). But contrary to the standard solutions for rules based systems (either forward or backward chaining), in this case here always complete binding sets are to be matched, which allows to reduce the effort.
@ -578,7 +578,7 @@ Aside from the index, handling of the advice provisions turns out to be tricky.
* management by ref-count was ruled out due to contention and locality considerations
* the most straight forward implementation would be for the ~AdviceProvision within the advisor to keep kind of an &quot;inofficial&quot; link to &quot;its&quot; provision, allowing to modify and retract it during the lifetime of the advisor. When going away without retracting (the default behaviour), the provision, as added into the system would remain there as a dangling entry. It is still reachable via the index, but not maintained in any further way. If memory usage turns out to be a problem, we'd need to enqueue these entries for clean-up.
* but as this simple solution contradicts the general advice semantics in a subtle way (see previous paragraph), we could insist on really re-capturing and retracting previous advice automatically on each new advice provision or modification. In this case, due to the requirement of thread safety, each addition, binding modification, placing of new advice or retraction would require to do an index search to find an existing provision with equivalent binding (same binding definition, not just a matching binding pattern). As a later provision could stomp upon an existing provision without the original advisor noticing this, we can't use the internal references anymore; we really need to search each time and also need a global lock during the modification transaction.
* an attempt to reduce this considerable overhead would be to use an back-link from the provision as added to the system to the original source (the ~AdviceProvision owned by the advisor). On modification, this original source would be notified and thus detached. Of course this is tricky to implement correctly, and also requires locking.
* an attempt to reduce this considerable overhead would be to use a back-link from the provision as added to the system to the original source (the ~AdviceProvision owned by the advisor). On modification, this original source would be notified and thus detached. Of course this is tricky to implement correctly, and also requires locking.
The decision for the initial implementation is to use the first variant and just accept the slightly imprecise semantics.
When copying a Provision, the hidden link to existing advice data is //not shared.//
@ -593,24 +593,24 @@ Behind the scenes, hidden within the {{{advice.cpp}}} implementation file, the ~
!!!!handling of default advice
Basically, the behaviour when requesting non-existing advice may be configured by policy. But the default policy is to return ref to a default constructed instance of the advice type in that case. Just the (implementation related) problem is that we return advice by {{{const&amp;}}}, not by value, so we're bound to create and manage this piece of default advice during the lifetime of the ~AdviceSystem. The way the ~AdviceSystem is accessed (only through the frontend of {{{advice::Request}}} and {{{advice::Provision}}} objects, in conjunction with the desire to control this behaviour by policy, creates a tricky implementation situation.
* regarding the lifecycle (and also from the logical viewpoint) it would be desirable to handle this &quot;default&quot; or &quot;no solution&quot; case similar to accessing an existing solution. But unfortunately doing so would require a fully typed context; thus basically on inserting a new request, when returning from the index search without a dedicated solution, we'd need to fabricate a fallback solution to insert it into the provision index, while still holding the index lock. At that point it is not determined if we ever need that fallback solution. Alternatively we could consider to fabricate this fallback solution on first unsuccessful advice fetch. But this seems sill worse, as it turns an (possibly even lock free) ptr access into an index operation. Having a very cheap advice access seems like an asset.
* regarding the lifecycle (and also from the logical viewpoint) it would be desirable to handle this &quot;default&quot; or &quot;no solution&quot; case similar to accessing an existing solution. But unfortunately doing so would require a fully typed context; thus basically on inserting a new request, when returning from the index search without a dedicated solution, we'd need to fabricate a fallback solution to insert it into the provision index, while still holding the index lock. At that point it is not determined if we ever need that fallback solution. Alternatively we could consider to fabricate this fallback solution on first unsuccessful advice fetch. But this seems sill worse, as it turns a (possibly even lock free) ptr access into an index operation. Having a very cheap advice access seems like an asset.
* on the other hand, using some separate kind of singleton bundle just for these default advice data (e.g. a templated version of //Meyer's Singleton...//), the fallback solution can be settled independent from the ~AdviceSystem, right in the {{{advice.hpp}}} and using static memory, but the downside is now the fallback solution might be destroyed prior to shutdown of the ~AdviceSystem, as it lives in another compilation unit.
Thus the second approach looks favourable, but we should //note the fact that it is hard to secure this possible access to an already destroyed solution,// unless we decline using the advice feature after the end of {{{main()}}}. Such a policy seems to be reasonable anyway, as the current implementation also has difficulties to prevent accessing an already destroyed {{{advice::Provision}}}, being incorporated in the ~AdviceSystem, but accessed through a direct pointer in the {{{advice::Request}}}.
!!!locking and exception safety
The advice system is (hopefully) written such as not to be corrupted in case an exception is thrown. Adding new requests, setting advice data on a provision and any binding change might fail due to exhausted memory. The advice system remains operational in this case, but the usual reaction would be //subsystem shutdown,// because the Advice facility typically is used in a very low-level manner, assuming it //just works.// As far as I can see, the other mutation operations can't throw.
The individual operations on the interface objects are //deliberately not thread-safe.// The general assumption is that {{{advice::Request}}} and {{{advice::Provision}}} will be used in a safe environment and not be accessed or modified concurrently. An notable exception to this rule is accessing Advice: as this just includes checking and dereferentiating a pointer, it might be done concurrently. But note, //the advice system does nothing to ensure visibility of the solution within a separate thread.// If this thread still has the old pointer value in his local cache, it won't pick up the new solution. In case the old solution got retracted, this even might cause access to already released objects. You have been warned. So it's probably a good idea to ensure a read barrier happens somewhere in the enclosing usage context prior to picking up a possibly changed advice solution concurrently.
The individual operations on the interface objects are //deliberately not thread-safe.// The general assumption is that {{{advice::Request}}} and {{{advice::Provision}}} will be used in a safe environment and not be accessed or modified concurrently. A notable exception to this rule is accessing Advice: as this just includes checking and dereferentiating a pointer, it might be done concurrently. But note, //the advice system does nothing to ensure visibility of the solution within a separate thread.// If this thread still has the old pointer value in his local cache, it won't pick up the new solution. In case the old solution got retracted, this even might cause access to already released objects. You have been warned. So it's probably a good idea to ensure a read barrier happens somewhere in the enclosing usage context prior to picking up a possibly changed advice solution concurrently.
''Note'': the underlying operations on the embedded global {{{advice::Index}}} obviously need to be protected by locking the whole index table on each mutation, which also ensures a memory barrier and thus propagates changed solutions. While this settles the problem for the moment, we might be forced into a more fine grained locking due to contention prolems later on...
!!!index datastructure
It is clear by now that the implementation datastrucutre has to serve as a kind of //reference count.// Within this datastructure, any constructed advice solution needs to be reflected somehow, to prevent us from discarding an advice provision still accessible. Allowing lock-free access to the advice solution (planned feature) adds an special twist, because in this case we can't even tell for sure if an overwritten old solution is actually gone (or if its still referred from some thread's cached memeory). This could be addressed with an transactional approach (which might be good anyway) &amp;mdash; but I tend to leave this special concern asside for now.
It is clear by now that the implementation datastructure has to serve as a kind of //reference count.// Within this datastructure, any constructed advice solution needs to be reflected somehow, to prevent us from discarding an advice provision still accessible. Allowing lock-free access to the advice solution (planned feature) adds a special twist, because in this case we can't even tell for sure if an overwritten old solution is actually gone (or if its still referred from some thread's cached memery). This could be addressed by employing a transactional approach (which might be good anyway) -- but I tend to leave this special concern aside for now.
To start with, any advice matching and solution will //always happen within matching buckets of a hash based pattern organisation.// The binding index thus should build on two hashtables (one for the requests and one for the provisions), but using specifically crafted datastructures as buckets. The individual entries within these bucket structures in both cases will be comprised of a binding matcher (to determine if an match actually happens) and a back-link to the registered entitiy (provision or request). Given the special pattern of the advice solutions, existing solutions could be tracked within the entries at the request side.
To start with, any advice matching and solution will //always happen within matching buckets of a hash based pattern organisation.// The first stage of each access involves using the correct binding pattern, and this binding pattern can be represented within the index data structure by the binding pattern's hash value. Since the advice typing can be translated at interface level into a further predicate within the binding, the use of these binding hashes as first access step also limits access to advice with proper type. All further access or mutation logic takes place within a sub structure corresponding to this top-level hash value. The binding index thus relies on two hashtables (one for the requests and one for the provisions), but using specifically crafted datastructures as buckets. The individual entries within these bucket sub structures in both cases will be comprised of a binding matcher (to determine if a match actually happens) and a back-link to the registered entitiy (provision or request). Given the special pattern of the advice solutions, existing solutions could be tracked within the entries at the request side.
* Advice provisions are expected to happen only in small numbers; they will be searched stack-like, starting from the newes provisions, until a match is found.
* Each advised entity basically creates an advice request, so there could be a larger number of request entries. In the typical search triggered from the provision side, each request entry will be visited and checked for match, which, if successful, causes a pointer to be set within the ~AdviceRequest object (located outside the realm of the advice system). While &amp;mdash; obviously &amp;mdash; multiple requests with similar binding match could be folded into a sub-list, we need actual timing measurements to determine the weight of these two calculation steps of matching and storing, which together comprise the handling of an advice solution.
* Each advised entity basically creates an advice request, so there could be a larger number of request entries. In the typical search triggered from the provision side, each request entry will be visited and checked for match, which, if successful, causes a pointer to be set within the ~AdviceRequest object (located outside the realm of the advice system). While -- obviously -- multiple requests with similar binding match could be folded into a sub-list, we need actual timing measurements to determine the weight of these two calculation steps of matching and storing, which together comprise the handling of an advice solution.
The above considerations don't fully solve the question how to represent an computed solution within the index datastructure, candidates being to use the index within the provision list, or a direct pointer to the provision or even just to re-use the pointer stored into the ~AdviceRequest. My decision is to do the latter. Besides solutions found by matching, we need //fallback solutions// holding a default constructed piece of advice of the requested type. As these defaults aren't correlated at all to the involved bindings, but only to the advice type as such, it seems reasonable to keep them completely apart, like e.g. placing them into static memory managed by the ~AdviceProvision template instantiations.
The above considerations don't fully solve the question how to represent a computed solution within the index data structure, candidates being to use the index within the provision list, or a direct pointer to the provision or even just to re-use the pointer stored into the ~AdviceRequest. My decision is to do the latter. Besides solutions found by matching, we need //fallback solutions// holding a default constructed piece of advice of the requested type. As these defaults aren't correlated at all to the involved bindings, but only to the advice type as such, it seems reasonable to keep them completely apart, like e.g. placing them into static memory managed by the ~AdviceProvision template instantiations.
!!!interactions to be served by the index
[&gt;img[Advice solution|draw/AdviceBindingIndex1.png]]
@ -628,9 +628,9 @@ The above considerations don't fully solve the question how to represent an comp
;modify provision
:add a new (copy of the) provision, followed by retracting the old one; actually these two traversals of all requests can be combined, thus treating a request which used the old provision but doesn't match the new one is treated like a new request
&lt;&lt;&lt;
__Invariant__: each request has a valid soultion pointer set (maybe pointing to a default solution). Whenever such a solution points to a registered provision, there is a match between the index entries and this is the top-most possible match to any provision entry for this request entry
__Invariant__: each request has a valid solution pointer set (maybe pointing to a default solution). Whenever such a solution points to a registered provision, there is a match between the index entries and this is the top-most possible match to any provision entry for this request entry
&lt;&lt;&lt;
Clearly, retracting advice (and consequently also the modification) is expensive. After finishing these operations, the old/retracted provision can be discarded (or put asside in case of non-locking advice access). Other operations don't cause de-allocation, as provisions remain within the system, even if the original advising entity is gone.
Clearly, retracting advice (and consequently also the modification) is expensive. After finishing these operations, the old/retracted provision can be discarded (or put aside in case of non-locking advice access). Other operations don't cause de-allocation, as provisions remain within the system, even if the original advising entity is gone.
</pre>
</div>
<div title="AdviceRequirements" modifier="Ichthyostega" modified="201005250339" created="201004060213" tags="design impl" changecount="21">
@ -1614,7 +1614,7 @@ For this to work, we need each of the //participating object types// to provide
@@clear(left):display(block):@@</pre>
</div>
<div title="ConfigRules" modifier="Ichthyostega" modified="201210280250" created="200801171352" tags="overview spec Rules" changecount="22">
<div title="ConfigRules" modifier="Ichthyostega" modified="201211252131" created="200801171352" tags="overview spec Rules" changecount="24">
<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 Lumiera 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 Lumiera'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.
@ -1624,8 +1624,8 @@ For this to work, we need each of the //participating object types// to provide
* actually building such a connection may create additional degrees of freedom, like panning for sound or layering for video.
!anatomy of a Configuration Query
The query is given as a number of logic predicates, which are required to be true. Syntactically, it is a string in prolog syntax, e.g. {{{stream(mpeg)}}}, where &quot;stream&quot; is the //predicate, // meaning here &quot;the stream type is...?&quot; and &quot;mpeg&quot; is a //term // denoting an actual property, object, thing, number etc &amp;mdash; the actual kind of stream in the given example. Multible comma separated predicates are combined with logical &quot;and&quot;. Terms may be //variable // at start, which is denoted syntactically by starting them with a uppercase letter. But any variable term need to be //bound // to some known value while computing the solution to the query, otherwise the query fails. A failed query is treated as a local failure, which may cause some operation being aborted or just some other possibility being chosen.
Queries are represented by instantiations of the {{{Query&lt;TYPE&gt;}}} template, because their actual meaning is &quot;retrieve or create an object of TYPE, configured such that...!&quot;. At the C++ side, this ensures type safety and fosters programming against interfaces, while being implemented rule-wise by silently prepending the query with the predicate &quot;{{{object(TYPE)}}}&quot;
The query is given as a number of logic predicates, which are required to be true. Syntactically, it is a string in prolog syntax, e.g. {{{stream(mpeg)}}}, where &quot;stream&quot; is the //predicate, // meaning here &quot;the stream type is...?&quot; and &quot;mpeg&quot; is a //term // denoting an actual property, object, thing, number etc &amp;mdash; the actual kind of stream in the given example. Multible comma separated predicates are combined with logical &quot;and&quot;. Terms may be //variable// at start, which is denoted syntactically by starting them with a uppercase letter. But, through the computation of a solution, any variable term needs to be //bound//&amp;nbsp; to some known fixed value, otherwise the counts as failed. A failed query is treated as a local failure, which may cause some operation being aborted or just some other possibility being chosen.
Queries are represented by instantiations of the {{{Query&lt;TYPE&gt;}}} template, because their actual meaning is &quot;retrieve or create an object of TYPE, configured such that...!&quot;. At the C++ side, this ensures type safety and fosters programming against interfaces, while being implemented rule-wise by silently prepending the query with the predicate {{{object(X, type)}}}, which reads as &quot;X is an object with this type&quot;
!!!querying for default
A special kind of configuration query includes the predicate {{{default(X)}}}, which is kind-of an existential quantisation of the variable {{{X}}}. Using this predicate states that a suitable //default-configured// object exists somehow. This behaviour could be used as an fallback within a config query, allowing us always to return a solution. The latter can be crucial when it comes to integrating the query subsystem into an existing piece of implementation logic, which requires us to give some guarantees.