lumiera_/src/common/config-rules.hpp

228 lines
8.6 KiB
C++
Raw Normal View History

/*
CONFIG-RULES.hpp - interface for rule based configuration
2010-12-17 23:28:49 +01:00
Copyright: clarify and simplify the file headers * Lumiera source code always was copyrighted by individual contributors * there is no entity "Lumiera.org" which holds any copyrights * Lumiera source code is provided under the GPL Version 2+ == Explanations == Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above. For this to become legally effective, the ''File COPYING in the root directory is sufficient.'' The licensing header in each file is not strictly necessary, yet considered good practice; attaching a licence notice increases the likeliness that this information is retained in case someone extracts individual code files. However, it is not by the presence of some text, that legally binding licensing terms become effective; rather the fact matters that a given piece of code was provably copyrighted and published under a license. Even reformatting the code, renaming some variables or deleting parts of the code will not alter this legal situation, but rather creates a derivative work, which is likewise covered by the GPL! The most relevant information in the file header is the notice regarding the time of the first individual copyright claim. By virtue of this initial copyright, the first author is entitled to choose the terms of licensing. All further modifications are permitted and covered by the License. The specific wording or format of the copyright header is not legally relevant, as long as the intention to publish under the GPL remains clear. The extended wording was based on a recommendation by the FSF. It can be shortened, because the full terms of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
Copyright (C)
2008, Hermann Vosseler <Ichthyostega@web.de>
2010-12-17 23:28:49 +01:00
Copyright: clarify and simplify the file headers * Lumiera source code always was copyrighted by individual contributors * there is no entity "Lumiera.org" which holds any copyrights * Lumiera source code is provided under the GPL Version 2+ == Explanations == Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above. For this to become legally effective, the ''File COPYING in the root directory is sufficient.'' The licensing header in each file is not strictly necessary, yet considered good practice; attaching a licence notice increases the likeliness that this information is retained in case someone extracts individual code files. However, it is not by the presence of some text, that legally binding licensing terms become effective; rather the fact matters that a given piece of code was provably copyrighted and published under a license. Even reformatting the code, renaming some variables or deleting parts of the code will not alter this legal situation, but rather creates a derivative work, which is likewise covered by the GPL! The most relevant information in the file header is the notice regarding the time of the first individual copyright claim. By virtue of this initial copyright, the first author is entitled to choose the terms of licensing. All further modifications are permitted and covered by the License. The specific wording or format of the copyright header is not legally relevant, as long as the intention to publish under the GPL remains clear. The extended wording was based on a recommendation by the FSF. It can be shortened, because the full terms of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
2010-12-17 23:28:49 +01:00
*/
/** @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
** implementation will be hidden behind a `instance` (Singleton factory). As of 1/2008,
** it is _planned_ to use an embedded YAP Prolog system at some point in the future,
** for now we use a [mock implementation](\ref fake-configrules.hpp) based on lookup in
** a hard-wired, 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...
**
** \par relation to Query and QueryResolver
** The ConfigRules resolver is just a special kind of QueryResolver, able to handle specific kinds
** of queries. Clients using the ConfigRules directly get a more easy to use point-and-shot style
** interface, allowing just to retrieve some _suitable solution_, instead of having to iterate
** through a result set.
**
** @todo right now (12/2012) the above paragraph is a lie.
** ConfigQuery is way older than QueryResolver and will be retrofitted step by step.
** Not much of a problem, since the currently utilised mock implementation isn't able to
** deal with a real query anyway.
**
** @note this is rather a concept draft and left as such for now... don't take this code too literal!
** @todo clarify the relation of config query and query-for-defaults ///////////////TICKET #705
** @todo as of 11/2016 the situation is basically the same: this is placeholder code
** and just implemented enough to keep us going without violating the architecture vision
**
** @see lumiera::Query
** @see mobject::session::DefsManager
** @see asset::StructFactory
** @see config-resolver.hpp specialised setup for the Steam-Layer
** @see fake-configrules.hpp currently used dummy-implementation
**
*/
#ifndef LUMIERA_CONFIG_RULES_H
#define LUMIERA_CONFIG_RULES_H
#include "lib/p.hpp"
#include "lib/symbol.hpp"
#include "lib/meta/generator.hpp"
#include "common/query.hpp"
#include <string>
namespace lumiera {
namespace error {
LUMIERA_ERROR_DECLARE (CAPABILITY_QUERY); ///< unresolvable capability query.
}
using std::string;
using lib::P;
/////////////////////////////////////////////////////////////////////TICKET #705 this is draft/preview code; a real resolution system needs to be integrated
namespace query {
// The intention is to support the following style of Prolog code
//
2008-02-29 18:58:29 +01:00
// resolve(O, Cap) :- find(O), capabilities(Cap).
// resolve(O, Cap) :- make(O), capabilities(Cap).
// capabilities(Q) :- call(Q).
//
// stream(T, mpeg) :- type(T, fork), 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 Fork object (a "track"), try to
// retrieve a pipe object with stream-type=mpeg and associate the Fork with this Pipe. The
// predicate "stream(P,mpeg)" needs to be implemented (natively) for the pipe object.
class Resolver
{
///////////////////////////////////////////////////////////////TICKET #705 a real resolution system needs to be integrated
};
using lib::Symbol;
using lib::Literal;
using lumiera::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.
* @deprecated it can't be done exactly this way, but I leave it in the
* current shape as a reminder for later, to show the intention...
* @todo 6/2010 unify this with the TypeHandler in typed-id.hpp
*/
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 Steam-Layer code can
* use this QueryHandler to retrieve instances of the
* type TY fulfilling the given Query. To start with,
2008-02-29 18:58:29 +01:00
* we use a mock implementation.
* (this code works and is already used 2/2008)
* @todo retrofit this to install and use a QueryResolver
* @see lumiera::query::LookupPreconfigured
* @see lumiera::query::MockTable
*/
template<class TY>
class QueryHandler
{
protected:
2008-01-29 05:39:32 +01:00
virtual ~QueryHandler() { }
public:
/** try to find or create an object of type TY
* fulfilling the given query.
2008-02-29 18:58:29 +01:00
* @param solution object fulfilling the query. Will be bound or
* unified (in case it's already bound) with the first solution.
* @param q any goals to be fulfilled by the solution.
2008-02-29 18:58:29 +01:00
* @return false if resolution failed. In this case, solution ptr is empty.
*/
virtual bool resolve (P<TY>& solution, Query<TY> const& 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<Fork>, 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
2011-12-03 02:56:50 +01:00
: public lib::meta::InstantiateForEach<TYPES, QueryHandler>
{
protected:
ConfigRules () {}
virtual ~ConfigRules() {}
public:
/** roll back to a pristine yet operational state.
* Discards all information collected through use */
virtual void reset() =0;
// TODO: find out what operations we need to support here for the »real solution« (using Prolog)
};
} // namespace query
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(lumiera::QueryKey const& q);
bool isFakeBypass (lumiera::QueryKey const& q);
/////////////////////////////////////////////////////////////////////////////TICKET 710
} // namespace query
} // namespace lumiera
#endif