00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00038 #ifndef LUMIERA_MOCKCONFIGRULES_H
00039 #define LUMIERA_MOCKCONFIGRULES_H
00040
00041 #include "proc/mobject/session.hpp"
00042 #include "common/configrules.hpp"
00043 #include "common/util.hpp"
00044
00045 #include <boost/scoped_ptr.hpp>
00046 #include <boost/any.hpp>
00047 #include <string>
00048 #include <map>
00049
00050
00051
00052 namespace lumiera
00053 {
00054
00055
00056 namespace query
00057 {
00058 using asset::Pipe;
00059 using asset::ProcPatt;
00060 using asset::PProcPatt;
00061 using mobject::Session;
00062
00063 using util::isnil;
00064
00065 using boost::any;
00066 using boost::any_cast;
00067
00068
00069
00070
00071
00072 namespace
00073 {
00074
00076 template<class TY>
00077 struct WrapReturn { typedef P<TY> Wrapper; };
00078
00079 template<>
00080 struct WrapReturn<ProcPatt> { typedef PProcPatt Wrapper; };
00081
00082
00086 inline bool
00087 is_defaults_query (string& query)
00088 {
00089 return !isnil (removeTerm ("default", query));
00090 }
00091 }
00092
00093
00098 class MockTable : public lumiera::ConfigRules
00099 {
00100 typedef std::map<string,any> Tab;
00101 typedef boost::scoped_ptr<Tab> PTab;
00102
00103 PTab answer_;
00104 bool isInit_;
00105
00106 protected:
00107 MockTable ();
00108 const any& fetch_from_table_for (const string& queryStr);
00109
00110
00111 template<class TY>
00112 bool detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q);
00113 bool fabricate_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID);
00114 bool fabricate_just_new_Pipe (Query<Pipe>& q);
00115 bool fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q, string const& streamID);
00116
00117 template<class TY>
00118 bool set_new_mock_solution (Query<TY>& q, typename WrapReturn<TY>::Wrapper& candidate);
00119
00120
00121 private:
00122 void fill_mock_table ();
00123 };
00124
00125
00131 template<class TY, class BASE>
00132 class LookupPreconfigured : public BASE
00133 {
00134 typedef typename WrapReturn<TY>::Wrapper Ret;
00135
00136 public:
00138 virtual bool
00139 resolve (Ret& solution, const Query<TY>& q)
00140 {
00141 const any& entry = fetch_from_table_for (q.asKey());
00142 if (!isnil (entry))
00143 {
00144 const Ret& candidate (any_cast<const Ret&> (entry));
00145 if (! solution
00146 ||(solution && solution == candidate)
00147 )
00148 return solution = candidate;
00149 }
00150 return try_special_case(solution, q);
00151 }
00152
00153 private:
00154 bool
00155 try_special_case (Ret& solution, const Query<TY>& q)
00156 {
00157 if (solution && isFakeBypass(q))
00158 return solution;
00159
00160 Query<TY> newQuery = q;
00161 if (is_defaults_query (newQuery))
00162 return solution = Session::current->defaults (newQuery);
00163
00164 if (detect_case (solution, newQuery))
00165 return resolve (solution, newQuery);
00166
00167 return solution = Ret();
00168 }
00169 };
00170
00171
00173 template<class TY>
00174 inline bool
00175 MockTable::detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q)
00176 {
00177 q.clear();
00178 return false;
00179 }
00180 template<>
00181 inline bool
00182 MockTable::detect_case (WrapReturn<Pipe>::Wrapper& candidate, Query<Pipe>& q)
00183 {
00184 if (!isnil (extractID("make", q)))
00185 return false;
00186
00187
00188
00189 const string pipeID = extractID("pipe", q);
00190 const string streamID = extractID("stream", q);
00191
00192 if (candidate && pipeID == candidate->getPipeID())
00193 return set_new_mock_solution (q, candidate);
00194
00195 if (!isnil(pipeID) && !isnil(streamID))
00196 return fabricate_matching_new_Pipe (q, pipeID, streamID);
00197
00198 if (!candidate && (!isnil(streamID) || !isnil(pipeID)))
00199 return fabricate_just_new_Pipe (q);
00200
00201 q.clear();
00202 return false;
00203 }
00204 template<>
00205 inline bool
00206 MockTable::detect_case (WrapReturn<const ProcPatt>::Wrapper& candidate, Query<const ProcPatt>& q)
00207 {
00208 if (!isnil (extractID("make", q)))
00209 return false;
00210
00211 const string streamID = extractID("stream", q);
00212 if (!candidate && !isnil(streamID))
00213 return fabricate_ProcPatt_on_demand (q, streamID);
00214
00215 q.clear();
00216 return false;
00217 }
00218
00219
00220
00221
00222
00223
00229 class MockConfigRules
00230 : public typelist::InstantiateChained < InterfaceTypes
00231 , LookupPreconfigured
00232 , MockTable
00233 >
00234 {
00235 protected:
00236 MockConfigRules ();
00237 friend class lumiera::singleton::StaticCreate<MockConfigRules>;
00238
00239 virtual ~MockConfigRules() {}
00240
00241 public:
00242
00243
00244 };
00245
00246
00247
00248
00249 }
00250
00251 }
00252 #endif