ScriptExecuter.cpp
Go to the documentation of this file.
00001 /*
00002  * ScriptExecuter.cpp
00003  *
00004  *  Created on: Oct 17, 2013
00005  *      Author: blackpc
00006  */
00007 
00008 #include <scriptable_monitor/ScriptExecuter.h>
00009 
00010 /*
00011  * Statics
00012  */
00013 
00014 boost::mutex                            ScriptExecuter::_executionMutex;
00015 
00016 PythonScript*                           ScriptExecuter::_currentScript = NULL;
00017 bool                                            ScriptExecuter::_runtime;
00018 bool                                            ScriptExecuter::_simulation;
00019 bool                                            ScriptExecuter::_validationFailed;
00020 vector<string>                          ScriptExecuter::_validationsPassed;
00021 vector<string>                          ScriptExecuter::_validationsFailed;
00022 map<string, string>             ScriptExecuter::_topicValues;
00023 
00024 PyMethodDef ScriptExecuter::MonitorPythonLib[] =
00025 {
00026         {"internal_function",   &ScriptExecuter::internalFunction,              METH_O, ""      },
00027         {"internal_validation", &ScriptExecuter::internalValidation,    METH_O, ""      },
00028         {"internal_topic",              &ScriptExecuter::internalTopic,                 METH_O, ""      },
00029         {NULL,                                  NULL,                                                                   0,              NULL}
00030 };
00031 
00032 ScriptExecuter::ScriptExecuter()
00033 {
00034         PythonExecuter::initModule("robil_monitor_lib", MonitorPythonLib);
00035 }
00036 
00037 CompilationResult ScriptExecuter::compile(PythonScript& script)
00038 {
00039         return PythonExecuter::compile(script.getSourceCode());
00040 }
00041 
00042 void ScriptExecuter::execute(PythonScript& pythonScript, ScriptInputType input)
00043 {
00044         boost::mutex::scoped_lock lock(_executionMutex);
00045 
00046         pythonScript.setValidationFailed(false);
00047 
00048         ScriptExecuter::_runtime = true;
00049         ScriptExecuter::_simulation = false;
00050         ScriptExecuter::_validationFailed = false;
00051         ScriptExecuter::_validationsFailed = vector<string>();
00052         ScriptExecuter::_validationsPassed = vector<string>();
00053         ScriptExecuter::_currentScript = &pythonScript;
00054         ScriptExecuter::_topicValues = input;
00055 
00056         PythonExecuter::execute(pythonScript.getSourceCode());
00057 }
00058 
00059 void ScriptExecuter::simulate(PythonScript& pythonScript)
00060 {
00061         boost::mutex::scoped_lock lock(_executionMutex);
00062 
00063         pythonScript.getUsedInternalFunction().clear();
00064         pythonScript.getUsedTopics().clear();
00065         pythonScript.setValidationFailed(false);
00066 
00067         ScriptExecuter::_runtime = true;
00068         ScriptExecuter::_simulation = true;
00069         ScriptExecuter::_validationFailed = false;
00070         ScriptExecuter::_validationsFailed.clear();
00071         ScriptExecuter::_validationsPassed.clear();
00072         ScriptExecuter::_currentScript = &pythonScript;
00073 
00074         PythonExecuter::execute(pythonScript.getSourceCode());
00075 }
00076 
00077 PyObject* ScriptExecuter::convertToPythonType(string object) {
00078         Yaml yaml = YamlFunctions::toYaml(object);
00079 
00080 //      cout << "Converting '" << object << "' to python type" << endl;
00081 
00082         // Empty value
00083         if (yaml.size() == 0) {
00084                 yaml = YamlFunctions::toYaml("[" + object + "]");
00085                 // return PyFloat_FromDouble(0);
00086         }
00087 
00088         // Single item
00089         if (yaml.size() == 1) {
00090 
00091                 string value = yaml[0].to<string>();
00092 
00093                 // Is boolean
00094                 boost::to_lower(value);
00095                 if (value == "true")
00096                         return PyBool_FromLong(1);
00097                 if (value == "false")
00098                         return PyBool_FromLong(0);
00099 
00100 
00101                 // Is Double?
00102                 char * p;
00103                 double d = strtod( value.c_str(), &p);
00104 
00105                 if ( * p == 0 )
00106                         return PyFloat_FromDouble(d);
00107 
00108                 // Must be string
00109                 return PyString_FromString(value.c_str());
00110         }
00111 
00112         // Array
00113         if (yaml.size() > 1) {
00114                 PyObject* list = PyList_New(yaml.size());
00115                 for(size_t i = 0; i < yaml.size(); i++)
00116                         PyList_SetItem(list, i, PyString_FromString(yaml[i].to<string>().c_str()));
00117 
00118                 return list;
00119         }
00120 
00121         return PyFloat_FromDouble(0);
00122 }
00123 
00124 PyObject* ScriptExecuter::internalTopic(PyObject* self, PyObject* args)
00125 {
00126         if (_validationFailed)
00127                 return PyString_FromString("0");
00128 
00129         string  scriptName      = PyString_AsString(PyTuple_GetItem(args, 0));
00130         string  topicName       = PyString_AsString(PyTuple_GetItem(args, 1));
00131 
00132         if (_simulation) {
00133                 _currentScript->addUsedTopic(topicName);
00134                 return PyString_FromString("0");
00135         }
00136 
00137         string value = _topicValues.count(topicName) > 0 ? _topicValues[topicName].c_str() : "0";
00138         return convertToPythonType(value);
00139 }
00140 
00141 PyObject* ScriptExecuter::internalValidation(PyObject* self, PyObject* args)
00142 {
00143         if (_validationFailed)
00144                 return PyString_FromString("");
00145 
00146         string  scriptName                      = PyString_AsString(PyTuple_GetItem(args, 0));
00147         bool    validationPassed        = PyObject_IsTrue(PyTuple_GetItem(args, 1));
00148         string  description             = PyString_AsString(PyTuple_GetItem(args, 2));
00149 
00150         if (_simulation)
00151                 _currentScript->addValidation(description);
00152 
00153         if (!validationPassed) {
00154                 _validationFailed = true;
00155                 _currentScript->setValidationFailed(true);
00156                 _currentScript->addFailedValidation(description);
00157         }
00158 
00159         return PyString_FromString("");
00160 }
00161 
00162 PyObject* ScriptExecuter::internalFunction(PyObject* self, PyObject* args)
00163 {
00164         if (_validationFailed)
00165                 return PyString_FromString("");
00166 
00167         long int argCount = PyTuple_Size(args);
00168         string scriptName = PyString_AsString(PyTuple_GetItem(args, 0));
00169         string functionName = PyString_AsString(PyTuple_GetItem(args, 1));
00170 
00171         vector<string> arguments;
00172         for (int i = 2; i < argCount; i++) {
00173                 string argument = PyString_AsString(PyTuple_GetItem(args, i));
00174                 arguments.push_back(argument);
00175         }
00176 
00177         if (_simulation) {
00178                 _currentScript->addUsedInternalFunction(functionName);
00179                 return PyString_FromString("0");
00180         } else {
00181 
00182                 InternalFunction* function = InternalFunctionsManager::resolve(functionName);
00183 
00184                 if (function == NULL)
00185                         return PyFloat_FromDouble(0);
00186 
00187                 Parameters input(arguments);
00188                 Parameters output = function->invoke(input);
00189 
00190                 if (output.size() == 1) {
00191                         return convertToPythonType("[" + output.get<string>(0) + "]");
00192                 }
00193 
00194                 if (output.size() > 1) {
00195                         PyObject* list = PyList_New(output.size());
00196 
00197                         for(size_t i = 0; i < output.size(); i++)
00198                                 PyList_SetItem(list, i, convertToPythonType("[" + output.get<string>(i) + "]"));
00199 
00200                         return list;
00201                 }
00202 
00203                 return PyFloat_FromDouble(0.9);
00204         }
00205 }


scriptable_monitor
Author(s):
autogenerated on Wed Aug 26 2015 16:21:30