2008-01-14 01:01:11 +01:00
|
|
|
/*
|
2008-12-18 08:54:33 +01:00
|
|
|
FAKE-CONFIGRULES.hpp - dummy implementation of the config rules system
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-03-10 08:38:59 +01:00
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2008, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-01-14 01:01:11 +01:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
2010-12-17 23:28:49 +01:00
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2008-01-14 01:01:11 +01:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-01-14 01:01:11 +01:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2008-01-14 01:01:11 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2008-12-18 08:54:33 +01:00
|
|
|
/** @file fake-configrules.hpp
|
2008-01-18 16:43:53 +01:00
|
|
|
** Mock/Test/Debugging Implementation of the config rules system.
|
2008-12-18 08:54:33 +01:00
|
|
|
** Instead of actually parsing/analysing/resolving queries, this implementation
|
2008-01-18 16:43:53 +01:00
|
|
|
** uses a Table of hard wired queries together with preconfigured object instances
|
|
|
|
|
** as answer values. As of 1/2008 it is used to "keep the implementation work going"
|
|
|
|
|
** -- later on, when we use a real Prolog interpreter, it still may be useful for
|
|
|
|
|
** testing and debugging.
|
2010-11-02 04:09:06 +01:00
|
|
|
**
|
|
|
|
|
** @todo to be removed in Alpha, when integrating a real resolution engine /////////////////TICKET #710
|
|
|
|
|
**
|
2008-03-10 08:38:59 +01:00
|
|
|
** @see lumiera::Query
|
|
|
|
|
** @see lumiera::ConfigRules
|
2008-01-18 16:43:53 +01:00
|
|
|
**
|
|
|
|
|
*/
|
2008-01-14 01:01:11 +01:00
|
|
|
|
2008-01-18 16:43:53 +01:00
|
|
|
|
2008-12-18 08:54:33 +01:00
|
|
|
#ifndef LUMIERA_FAKECONFIGRULES_H
|
|
|
|
|
#define LUMIERA_FAKECONFIGRULES_H
|
2008-01-18 16:43:53 +01:00
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
#include "proc/mobject/session.hpp"
|
2008-12-18 08:54:33 +01:00
|
|
|
#include "common/configrules.hpp"
|
2008-12-17 17:53:32 +01:00
|
|
|
#include "lib/util.hpp"
|
2008-01-14 01:01:11 +01:00
|
|
|
|
2008-02-10 17:23:16 +01:00
|
|
|
#include <boost/scoped_ptr.hpp>
|
2008-02-06 05:34:19 +01:00
|
|
|
#include <boost/any.hpp>
|
2008-01-14 01:01:11 +01:00
|
|
|
#include <string>
|
2008-02-10 17:23:16 +01:00
|
|
|
#include <map>
|
2008-01-14 01:01:11 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-03-01 05:36:18 +01:00
|
|
|
namespace lumiera {
|
|
|
|
|
namespace query {
|
|
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
using asset::Pipe;
|
2008-01-28 06:05:46 +01:00
|
|
|
using asset::ProcPatt;
|
|
|
|
|
using asset::PProcPatt;
|
2008-04-06 20:11:34 +02:00
|
|
|
using mobject::Session;
|
2008-01-14 01:01:11 +01:00
|
|
|
|
2008-02-10 17:23:16 +01:00
|
|
|
using util::isnil;
|
|
|
|
|
|
2008-02-06 05:34:19 +01:00
|
|
|
using boost::any;
|
|
|
|
|
using boost::any_cast;
|
|
|
|
|
|
|
|
|
|
|
2008-02-10 17:23:16 +01:00
|
|
|
|
2008-02-06 05:34:19 +01:00
|
|
|
|
2008-04-07 03:19:24 +02:00
|
|
|
|
2010-03-01 05:36:18 +01:00
|
|
|
namespace { // internal details
|
2008-04-07 03:19:24 +02:00
|
|
|
|
|
|
|
|
/** a traits-class to define the smart-ptr to wrap the result */
|
|
|
|
|
template<class TY>
|
2008-05-19 08:46:19 +02:00
|
|
|
struct WrapReturn { typedef P<TY> Wrapper; };
|
2008-04-07 03:19:24 +02:00
|
|
|
|
|
|
|
|
template<>
|
|
|
|
|
struct WrapReturn<ProcPatt> { typedef PProcPatt Wrapper; };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** helper detecting if a query actually intended to retrieve a "default" object.
|
2010-03-01 05:36:18 +01:00
|
|
|
* This implementation is quite crude, of course it would be necessary actually to
|
2008-04-07 03:19:24 +02:00
|
|
|
* parse and evaluate the query. @note query is modified if "default" ... */
|
|
|
|
|
inline bool
|
|
|
|
|
is_defaults_query (string& query)
|
|
|
|
|
{
|
|
|
|
|
return !isnil (removeTerm ("default", query));
|
|
|
|
|
}
|
2010-03-01 05:36:18 +01:00
|
|
|
|
2008-04-07 03:19:24 +02:00
|
|
|
} // details (end)
|
2008-02-06 05:34:19 +01:00
|
|
|
|
|
|
|
|
|
2010-03-01 05:36:18 +01:00
|
|
|
|
2008-02-06 05:34:19 +01:00
|
|
|
/**
|
|
|
|
|
* the actual table holding preconfigured answers
|
|
|
|
|
* packaged as boost::any objects.
|
|
|
|
|
*/
|
2008-03-10 08:38:59 +01:00
|
|
|
class MockTable : public lumiera::ConfigRules
|
2008-02-06 05:34:19 +01:00
|
|
|
{
|
2008-02-10 17:23:16 +01:00
|
|
|
typedef std::map<string,any> Tab;
|
|
|
|
|
typedef boost::scoped_ptr<Tab> PTab;
|
|
|
|
|
|
|
|
|
|
PTab answer_;
|
2008-02-13 04:41:58 +01:00
|
|
|
bool isInit_;
|
2008-02-10 17:23:16 +01:00
|
|
|
|
2008-02-06 05:34:19 +01:00
|
|
|
protected:
|
|
|
|
|
MockTable ();
|
|
|
|
|
const any& fetch_from_table_for (const string& queryStr);
|
2008-02-10 17:23:16 +01:00
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
// special cases....
|
2008-04-07 03:19:24 +02:00
|
|
|
template<class TY>
|
2008-04-07 08:03:22 +02:00
|
|
|
bool detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q);
|
2008-04-06 20:11:34 +02:00
|
|
|
bool fabricate_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID);
|
2010-11-02 04:09:06 +01:00
|
|
|
bool fabricate_just_new_Pipe (Query<Pipe>& q);
|
2010-03-01 05:36:18 +01:00
|
|
|
bool fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q);
|
2010-10-26 04:54:51 +02:00
|
|
|
bool fabricate_Timeline_on_demand (Query<asset::Timeline>& q);
|
|
|
|
|
bool fabricate_Sequence_on_demand (Query<asset::Sequence>& q);
|
2008-04-07 08:03:22 +02:00
|
|
|
|
|
|
|
|
template<class TY>
|
|
|
|
|
bool set_new_mock_solution (Query<TY>& q, typename WrapReturn<TY>::Wrapper& candidate);
|
2008-04-06 20:11:34 +02:00
|
|
|
|
|
|
|
|
|
2008-02-10 17:23:16 +01:00
|
|
|
private:
|
|
|
|
|
void fill_mock_table ();
|
2008-02-06 05:34:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* building block defining how to do
|
2008-02-22 04:58:37 +01:00
|
|
|
* the mock implementation for \e one type.
|
2008-02-06 05:34:19 +01:00
|
|
|
* We simply access a table holding pre-created objects.
|
|
|
|
|
*/
|
|
|
|
|
template<class TY, class BASE>
|
|
|
|
|
class LookupPreconfigured : public BASE
|
|
|
|
|
{
|
|
|
|
|
typedef typename WrapReturn<TY>::Wrapper Ret;
|
|
|
|
|
|
|
|
|
|
public:
|
2008-02-29 18:58:29 +01:00
|
|
|
/** (dummy) implementation of the QueryHandler interface */
|
|
|
|
|
virtual bool
|
2010-10-26 04:54:51 +02:00
|
|
|
resolve (Ret& solution, Query<TY> const& q)
|
2008-02-06 05:34:19 +01:00
|
|
|
{
|
2008-02-10 17:23:16 +01:00
|
|
|
const any& entry = fetch_from_table_for (q.asKey());
|
|
|
|
|
if (!isnil (entry))
|
2008-03-31 03:21:28 +02:00
|
|
|
{
|
2010-10-26 04:54:51 +02:00
|
|
|
Ret const& candidate (any_cast<Ret const&> (entry));
|
2008-03-31 03:21:28 +02:00
|
|
|
if (! solution
|
2008-04-05 07:26:54 +02:00
|
|
|
||(solution && solution == candidate) // simulates a real unification
|
2008-03-31 03:21:28 +02:00
|
|
|
)
|
|
|
|
|
return solution = candidate;
|
|
|
|
|
}
|
2008-04-06 20:11:34 +02:00
|
|
|
return try_special_case(solution, q);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool
|
2010-10-26 04:54:51 +02:00
|
|
|
try_special_case (Ret& solution, Query<TY> const& q)
|
2008-04-06 20:11:34 +02:00
|
|
|
{
|
2008-04-07 08:03:22 +02:00
|
|
|
if (solution && isFakeBypass(q)) // backdoor for tests
|
|
|
|
|
return solution;
|
|
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
Query<TY> newQuery = q;
|
2008-04-07 03:19:24 +02:00
|
|
|
if (is_defaults_query (newQuery)) // modified query..
|
2008-04-06 20:11:34 +02:00
|
|
|
return solution = Session::current->defaults (newQuery);
|
2008-04-07 03:19:24 +02:00
|
|
|
// may cause recursion
|
2008-04-07 08:03:22 +02:00
|
|
|
if (detect_case (solution, newQuery))
|
2008-04-06 20:11:34 +02:00
|
|
|
return resolve (solution, newQuery);
|
2008-02-29 18:58:29 +01:00
|
|
|
|
2008-04-07 03:19:24 +02:00
|
|
|
return solution = Ret(); // fail: return default-constructed empty smart ptr
|
2008-02-06 05:34:19 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
/** Hook for treating very special cases for individual types only */
|
2008-04-07 03:19:24 +02:00
|
|
|
template<class TY>
|
2008-04-06 20:11:34 +02:00
|
|
|
inline bool
|
2008-04-07 08:03:22 +02:00
|
|
|
MockTable::detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q)
|
2008-04-06 20:11:34 +02:00
|
|
|
{
|
|
|
|
|
q.clear(); // end recursion
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2008-04-07 03:19:24 +02:00
|
|
|
template<>
|
2008-04-06 20:11:34 +02:00
|
|
|
inline bool
|
2008-04-07 08:03:22 +02:00
|
|
|
MockTable::detect_case (WrapReturn<Pipe>::Wrapper& candidate, Query<Pipe>& q)
|
2008-04-06 20:11:34 +02:00
|
|
|
{
|
2008-04-08 03:21:24 +02:00
|
|
|
if (!isnil (extractID("make", q)))
|
2010-11-02 04:09:06 +01:00
|
|
|
// used by tests to force fabrication of a new "solution"
|
|
|
|
|
return fabricate_just_new_Pipe (q);
|
2008-04-08 03:21:24 +02:00
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
const string pipeID = extractID("pipe", q);
|
|
|
|
|
const string streamID = extractID("stream", q);
|
2008-04-07 08:03:22 +02:00
|
|
|
|
|
|
|
|
if (candidate && pipeID == candidate->getPipeID())
|
|
|
|
|
return set_new_mock_solution (q, candidate); // "learn" this solution to be "valid"
|
|
|
|
|
|
2008-04-06 20:11:34 +02:00
|
|
|
if (!isnil(pipeID) && !isnil(streamID))
|
2008-04-07 08:03:22 +02:00
|
|
|
return fabricate_matching_new_Pipe (q, pipeID, streamID);
|
2008-04-08 03:21:24 +02:00
|
|
|
|
2008-04-08 04:39:07 +02:00
|
|
|
if (!candidate && (!isnil(streamID) || !isnil(pipeID)))
|
|
|
|
|
return fabricate_just_new_Pipe (q);
|
2008-04-06 20:11:34 +02:00
|
|
|
|
|
|
|
|
q.clear();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
template<>
|
|
|
|
|
inline bool
|
2008-04-07 08:03:22 +02:00
|
|
|
MockTable::detect_case (WrapReturn<const ProcPatt>::Wrapper& candidate, Query<const ProcPatt>& q)
|
2008-04-06 20:11:34 +02:00
|
|
|
{
|
|
|
|
|
const string streamID = extractID("stream", q);
|
2010-11-02 04:09:06 +01:00
|
|
|
|
2008-04-07 08:03:22 +02:00
|
|
|
if (!candidate && !isnil(streamID))
|
2010-03-01 05:36:18 +01:00
|
|
|
return fabricate_ProcPatt_on_demand (q);
|
2008-04-06 20:11:34 +02:00
|
|
|
|
|
|
|
|
q.clear();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2010-10-26 04:54:51 +02:00
|
|
|
template<>
|
|
|
|
|
inline bool
|
|
|
|
|
MockTable::detect_case (WrapReturn<asset::Timeline>::Wrapper& candidate, Query<asset::Timeline>& q)
|
|
|
|
|
{
|
|
|
|
|
if (!candidate)
|
|
|
|
|
return fabricate_Timeline_on_demand (q);
|
|
|
|
|
|
|
|
|
|
q.clear();
|
|
|
|
|
return bool(candidate);
|
|
|
|
|
}
|
|
|
|
|
template<>
|
|
|
|
|
inline bool
|
|
|
|
|
MockTable::detect_case (WrapReturn<asset::Sequence>::Wrapper& candidate, Query<asset::Sequence>& q)
|
|
|
|
|
{
|
|
|
|
|
if (!candidate)
|
|
|
|
|
return fabricate_Sequence_on_demand (q);
|
|
|
|
|
|
|
|
|
|
q.clear();
|
|
|
|
|
return bool(candidate);
|
|
|
|
|
}
|
2008-04-06 20:11:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-01-19 14:24:24 +01:00
|
|
|
/**
|
2008-04-06 20:11:34 +02:00
|
|
|
* Facade: Dummy Implementation of the query interface.
|
2008-01-21 02:57:09 +01:00
|
|
|
* Provides an explicit implementation using hard wired
|
|
|
|
|
* values for some types of interest for testing and debugging.
|
2008-01-19 14:24:24 +01:00
|
|
|
*/
|
2008-02-06 05:34:19 +01:00
|
|
|
class MockConfigRules
|
|
|
|
|
: public typelist::InstantiateChained < InterfaceTypes
|
|
|
|
|
, LookupPreconfigured // building block used for each of the types
|
|
|
|
|
, MockTable // for implementing the base class (interface)
|
|
|
|
|
>
|
2008-01-19 14:24:24 +01:00
|
|
|
{
|
|
|
|
|
protected:
|
2008-02-06 05:34:19 +01:00
|
|
|
MockConfigRules (); ///< to be used only by the singleton factory
|
2009-09-30 00:27:14 +02:00
|
|
|
friend class lib::singleton::StaticCreate<MockConfigRules>;
|
2008-01-29 05:39:32 +01:00
|
|
|
|
|
|
|
|
virtual ~MockConfigRules() {}
|
2008-01-19 14:24:24 +01:00
|
|
|
|
|
|
|
|
public:
|
2008-01-21 02:57:09 +01:00
|
|
|
|
2010-03-01 05:36:18 +01:00
|
|
|
// TODO: implementation of any additional functions on the ConfigRules interface goes here
|
2008-01-19 14:24:24 +01:00
|
|
|
};
|
2008-02-06 05:34:19 +01:00
|
|
|
|
2008-01-19 14:24:24 +01:00
|
|
|
|
2008-01-14 01:01:11 +01:00
|
|
|
|
|
|
|
|
|
2010-03-01 05:36:18 +01:00
|
|
|
}} // namespace lumiera::query
|
2008-01-14 01:01:11 +01:00
|
|
|
#endif
|