diff options
author | randomdan <randomdan@localhost> | 2013-03-16 17:35:08 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2013-03-16 17:35:08 +0000 |
commit | 7f8946eae1eae62c3140bed25bde9719c720bf35 (patch) | |
tree | 461a6ea8c73a8472a6dd6a3b70d8eba591e09253 /project2/common/variables | |
parent | Fix the case where the routing table wasn't cleared before reload (diff) | |
download | project2-7f8946eae1eae62c3140bed25bde9719c720bf35.tar.bz2 project2-7f8946eae1eae62c3140bed25bde9719c720bf35.tar.xz project2-7f8946eae1eae62c3140bed25bde9719c720bf35.zip |
Folderise variables and another test
Diffstat (limited to 'project2/common/variables')
-rw-r--r-- | project2/common/variables/config.cpp | 87 | ||||
-rw-r--r-- | project2/common/variables/fixed.cpp | 13 | ||||
-rw-r--r-- | project2/common/variables/fixed.h | 17 | ||||
-rw-r--r-- | project2/common/variables/literal.cpp | 78 | ||||
-rw-r--r-- | project2/common/variables/literal.h | 40 | ||||
-rw-r--r-- | project2/common/variables/localparam.cpp | 31 | ||||
-rw-r--r-- | project2/common/variables/lookup.cpp | 74 | ||||
-rw-r--r-- | project2/common/variables/param.cpp | 31 | ||||
-rw-r--r-- | project2/common/variables/session.cpp | 31 | ||||
-rw-r--r-- | project2/common/variables/uri.cpp | 31 |
10 files changed, 433 insertions, 0 deletions
diff --git a/project2/common/variables/config.cpp b/project2/common/variables/config.cpp new file mode 100644 index 0000000..67014c4 --- /dev/null +++ b/project2/common/variables/config.cpp @@ -0,0 +1,87 @@ +#include <pch.hpp> +#include "../variables.h" +#include "../scriptLoader.h" +#include "../scriptStorage.h" +#include <boost/algorithm/string/predicate.hpp> +#include "../appEngine.h" + +typedef std::map<Glib::ustring, Glib::ustring> ConfigOptions; +static ConfigOptions cfgOpts; + +SimpleMessageException(NoSuchConfigurationValue); + +/// Variable implementation to access platform configuration values +class VariableConfig : public VariableImplDyn { + public: + VariableConfig(ScriptNodePtr e) : + VariableImplDyn(e), + name(e->value("name").as<Glib::ustring>()) + { + } + VariableType value() const + { + const ConfigOptions::const_iterator i = cfgOpts.find(name); + if (i != cfgOpts.end()) { + return i->second; + } + if (defaultValue) { + return defaultValue.get()(); + } + throw NoSuchConfigurationValue(name); + } + private: + const Glib::ustring name; +}; + +class VariableConfigLoader : public VariableLoader::For<VariableConfig> { + public: + class AppSettings : public Options::Option { + public: + void reset() const { + cfgOpts.clear(); + } + void consume(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v) const { + if (boost::algorithm::starts_with(n, "application.")) { + Glib::ustring k(n.substr(12)); + const ConfigOptions::iterator i = cfgOpts.find(k); + if (i == cfgOpts.end()) { + if (p.empty() || p == Environment::getCurrent()->platform()) { + cfgOpts.insert(ConfigOptions::value_type(k, v)); + } + } + else { + if (p == Environment::getCurrent()->platform()) { + i->second = v; + } + } + } + } + bool accepts(const Glib::ustring & n) const { + return (boost::algorithm::starts_with(n, "application.")); + } + bool paramRequired() const { + return true; + } + Glib::ustring name() const { + return "application.*"; + } + Glib::ustring description() const { + return "Load settings into the client application"; + } + }; + VariableConfigLoader() : + opts("Variables - ModConfig options") + { + opts(new AppSettings()); + } + + const Options * options() const { + return &opts; + } + + private: + Options opts; +}; + +DECLARE_CUSTOM_COMPONENT_LOADER("config", VariableConfigLoader, VariableConfigLoader, VariableLoader); + diff --git a/project2/common/variables/fixed.cpp b/project2/common/variables/fixed.cpp new file mode 100644 index 0000000..fdb67ed --- /dev/null +++ b/project2/common/variables/fixed.cpp @@ -0,0 +1,13 @@ +#include "fixed.h" + +VariableFixed::VariableFixed(VariableType v) : + var(v) +{ +} + +VariableType +VariableFixed::value() const +{ + return var; +} + diff --git a/project2/common/variables/fixed.h b/project2/common/variables/fixed.h new file mode 100644 index 0000000..ec8be1a --- /dev/null +++ b/project2/common/variables/fixed.h @@ -0,0 +1,17 @@ +#ifndef VARIABLES_MODFIXED_H +#define VARIABLES_MODFIXED_H + +#include "../variables.h" + +/// Variable implementation which has some fixed value +class VariableFixed : public VariableImpl { + public: + VariableFixed(VariableType v); + VariableType value() const; + + private: + VariableType var; +}; + +#endif + diff --git a/project2/common/variables/literal.cpp b/project2/common/variables/literal.cpp new file mode 100644 index 0000000..11fb78a --- /dev/null +++ b/project2/common/variables/literal.cpp @@ -0,0 +1,78 @@ +#include "literal.h" +#include "../scripts.h" +#include <boost/foreach.hpp> +#include <boost/bind.hpp> + +/// Variable implementation whose value is a literal value of some known type +VariableLiteral::VariableLiteral(const Glib::ustring & src, const VT_typeID format) : + val(VariableType::make(src, format)) +{ +} + +template <typename X, typename Y> +static +void +append(VariableLiteral::Vals * vals, const Y & y) +{ + vals->push_back(new X(y)); +} + +VariableLiteral::VariableLiteral(ScriptNodePtr s) { + try { + val = VariableType::make(s->value("value"), VariableType::getTypeFromName(s->value("type", ""))); + } + catch (const ValueNotFound &) { + s->composeWithCallbacks( + boost::bind(&append<TextPart, Glib::ustring>, &vals, _1), + boost::bind(&append<VarPart, ScriptNodePtr>, &vals, _1)); + } +} + +VariableType +VariableLiteral::value() const +{ + if (vals.empty()) { + return val; + } + if (vals.size() == 1) { + return *vals.front(); + } + Glib::ustring v; + BOOST_FOREACH(PartCPtr p, vals) { + p->appendTo(v); + } + return v; +} + +VariableLiteral::TextPart::TextPart(const Glib::ustring & e) : + txt(e) +{ +} +void +VariableLiteral::TextPart::appendTo(Glib::ustring & str) const +{ + str += txt; +} +VariableLiteral::TextPart::operator VariableType() const +{ + return txt; +} + +VariableLiteral::VarPart::VarPart(ScriptNodePtr e) : Variable(e) +{ +} +void +VariableLiteral::VarPart::appendTo(Glib::ustring & str) const +{ + str += (*this)().operator const Glib::ustring &(); +} +VariableLiteral::VarPart::operator VariableType() const +{ + return (*this)(); +} + +DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader); +DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoader::For<VariableLiteral>, VariableLoader); + + + diff --git a/project2/common/variables/literal.h b/project2/common/variables/literal.h new file mode 100644 index 0000000..4128d1c --- /dev/null +++ b/project2/common/variables/literal.h @@ -0,0 +1,40 @@ +#ifndef VARIABLES_MODLITERAL_H +#define VARIABLES_MODLITERAL_H + +#include "../variables.h" +#include <list> + +class VariableLiteral : public VariableImpl { + public: + VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType); + VariableLiteral(ScriptNodePtr); + virtual VariableType value() const; + class Part; + typedef boost::intrusive_ptr<Part> PartCPtr; + typedef std::list<PartCPtr> Vals; + + class Part : public IntrusivePtrBase { + public: + virtual void appendTo(Glib::ustring & str) const = 0; + virtual operator VariableType() const = 0; + }; + class TextPart : public Part { + public: + TextPart(const Glib::ustring & e); + void appendTo(Glib::ustring & str) const; + operator VariableType() const; + const Glib::ustring txt; + }; + class VarPart : public Part, public Variable { + public: + VarPart(ScriptNodePtr e); + void appendTo(Glib::ustring & str) const; + operator VariableType() const; + }; + private: + VariableType val; + Vals vals; +}; + +#endif + diff --git a/project2/common/variables/localparam.cpp b/project2/common/variables/localparam.cpp new file mode 100644 index 0000000..1b789a7 --- /dev/null +++ b/project2/common/variables/localparam.cpp @@ -0,0 +1,31 @@ +#include <pch.hpp> +#include "../variables.h" +#include "../scriptLoader.h" +#include "../scriptStorage.h" +#include "../iHaveParameters.h" + +/// Variable implementation to access call parameters +class VariableLocalParam : public VariableImplDyn { + public: + VariableLocalParam(ScriptNodePtr e) : + VariableImplDyn(e), + name(e->value("name").as<Glib::ustring>()) + { + } + VariableType value() const + { + try { + return IHaveParameters::getScopedParameter(name); + } + catch (ParamNotFound) { + if (!defaultValue) { + throw; + } + return (*defaultValue)(); + } + } + private: + const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("local", VariableLocalParam, VariableLoader); + diff --git a/project2/common/variables/lookup.cpp b/project2/common/variables/lookup.cpp new file mode 100644 index 0000000..892968e --- /dev/null +++ b/project2/common/variables/lookup.cpp @@ -0,0 +1,74 @@ +#include <pch.hpp> +#include "../variables.h" +#include "../safeMapFind.h" +#include "../logger.h" +#include "../rowProcessor.h" +#include "../rowSet.h" +#include <boost/foreach.hpp> +#include "../scriptLoader.h" +#include "../scriptStorage.h" + + +/// Variable implementation that looks up it's value in a map of key(s)/value pairs +class VariableLookup : public VariableImplDyn, public RowProcessor { + private: + typedef std::vector<VariableType> Key; + typedef std::map<Key, VariableType> Map; + public: + class NotFound : public std::runtime_error { + public: + NotFound(const Key & k) : + std::runtime_error(mklist(k)) { + } + static std::string mklist(const Key & k) { + std::string l("("); + for (Key::const_iterator kp = k.begin(); kp != k.end(); ++kp) { + if (kp != k.begin()) l += ", "; + l += kp->operator const std::string &(); + } + l += ")"; + return l; + } + }; + VariableLookup(ScriptNodePtr e) : + VariableImplDyn(e), + RowProcessor(e), + name(e->value("name").as<Glib::ustring>()) + { + e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&rowSets)); + } + VariableType value() const + { + if (map.empty()) { + fillCache(); + } + Key k; + k.reserve(parameters.size()); + BOOST_FOREACH(const Parameters::value_type & p, parameters) { + k.push_back(p.second); + } + return safeMapLookup<NotFound>(map, k); + } + private: + void fillCache() const + { + BOOST_FOREACH(const RowSets::value_type & rs, rowSets) { + rs->execute(filter, this); + } + Logger()->messagef(LOG_DEBUG, "%s: %s has filled cached with %zu items", + __PRETTY_FUNCTION__, name.c_str(), map.size()); + } + void rowReady(const RowState * rs) const + { + Key k; + BOOST_FOREACH(const Parameters::value_type & p, parameters) { + k.push_back(rs->getCurrentValue(p.first)); + } + map[k] = rs->getCurrentValue(name); + } + mutable Map map; + typedef ANONSTORAGEOF(RowSet) RowSets; + RowSets rowSets; + const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("lookup", VariableLookup, VariableLoader); diff --git a/project2/common/variables/param.cpp b/project2/common/variables/param.cpp new file mode 100644 index 0000000..7292b0a --- /dev/null +++ b/project2/common/variables/param.cpp @@ -0,0 +1,31 @@ +#include <pch.hpp> +#include "../variables.h" +#include "../scriptLoader.h" +#include "../scriptStorage.h" +#include "../appEngine.h" + +/// Variable implementation to access call parameters +class VariableParam : public VariableImplDyn { + public: + VariableParam(ScriptNodePtr e) : + VariableImplDyn(e), + name(e->value("name").as<Glib::ustring>()) + { + } + VariableType value() const + { + try { + return ApplicationEngine::getCurrent()->env()->getParamQuery(name); + } + catch (ParamNotFound) { + if (!defaultValue) { + throw; + } + return (*defaultValue)(); + } + } + private: + const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("param", VariableParam, VariableLoader); + diff --git a/project2/common/variables/session.cpp b/project2/common/variables/session.cpp new file mode 100644 index 0000000..fc33d8e --- /dev/null +++ b/project2/common/variables/session.cpp @@ -0,0 +1,31 @@ +#include <pch.hpp> +#include "../variables.h" +#include "../scriptLoader.h" +#include "../scriptStorage.h" +#include "../appEngine.h" + +/// Variable implementation to access session contents +class VariableSession : public VariableImplDyn { + public: + VariableSession(ScriptNodePtr e) : + VariableImplDyn(e), + name(e->value("name").as<Glib::ustring>()) + { + } + VariableType value() const + { + try { + return ApplicationEngine::getCurrent()->session()->GetValue(name); + } + catch (Session::VariableNotFound) { + if (!defaultValue) { + throw; + } + return (*defaultValue)(); + } + } + private: + const Glib::ustring name; +}; +DECLARE_COMPONENT_LOADER("session", VariableSession, VariableLoader); + diff --git a/project2/common/variables/uri.cpp b/project2/common/variables/uri.cpp new file mode 100644 index 0000000..c5e596f --- /dev/null +++ b/project2/common/variables/uri.cpp @@ -0,0 +1,31 @@ +#include <pch.hpp> +#include "../variables.h" +#include "../scriptLoader.h" +#include "../scriptStorage.h" +#include "../appEngine.h" + +/// Variable implementation to access URI path fragments +class VariableUri : public VariableImplDyn { + public: + VariableUri(ScriptNodePtr e) : + VariableImplDyn(e), + index(e, "index") + { + } + VariableType value() const + { + try { + return ApplicationEngine::getCurrent()->env()->getParamUri(index()); + } + catch (UriElementOutOfRange) { + if (!defaultValue) { + throw; + } + return (*defaultValue)(); + } + } + private: + Variable index; +}; +DECLARE_COMPONENT_LOADER("uri", VariableUri, VariableLoader); + |