Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <scriptable_monitor/ScriptExecuter.h>
00009
00010
00011
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
00081
00082
00083 if (yaml.size() == 0) {
00084 yaml = YamlFunctions::toYaml("[" + object + "]");
00085
00086 }
00087
00088
00089 if (yaml.size() == 1) {
00090
00091 string value = yaml[0].to<string>();
00092
00093
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
00102 char * p;
00103 double d = strtod( value.c_str(), &p);
00104
00105 if ( * p == 0 )
00106 return PyFloat_FromDouble(d);
00107
00108
00109 return PyString_FromString(value.c_str());
00110 }
00111
00112
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 }