summaryrefslogtreecommitdiff
path: root/project2/common/variables
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2013-03-16 17:35:08 +0000
committerrandomdan <randomdan@localhost>2013-03-16 17:35:08 +0000
commit7f8946eae1eae62c3140bed25bde9719c720bf35 (patch)
tree461a6ea8c73a8472a6dd6a3b70d8eba591e09253 /project2/common/variables
parentFix the case where the routing table wasn't cleared before reload (diff)
downloadproject2-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.cpp87
-rw-r--r--project2/common/variables/fixed.cpp13
-rw-r--r--project2/common/variables/fixed.h17
-rw-r--r--project2/common/variables/literal.cpp78
-rw-r--r--project2/common/variables/literal.h40
-rw-r--r--project2/common/variables/localparam.cpp31
-rw-r--r--project2/common/variables/lookup.cpp74
-rw-r--r--project2/common/variables/param.cpp31
-rw-r--r--project2/common/variables/session.cpp31
-rw-r--r--project2/common/variables/uri.cpp31
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);
+