OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WSCRIPTINTERPRETERPYTHON_H 00026 #define WSCRIPTINTERPRETERPYTHON_H 00027 00028 #ifdef PYTHON_FOUND 00029 00030 #include <queue> 00031 #include <string> 00032 #include <vector> 00033 00034 #include <boost/thread/mutex.hpp> 00035 #include <boost/python.hpp> 00036 00037 #include "../../common/WThreadedRunner.h" 00038 00039 #include "../wrappers/WLoggerWrapper.h" 00040 #include "../wrappers/WModuleContainerWrapper.h" 00041 00042 #include "../WScriptInterpreter.h" 00043 00044 namespace pb = boost::python; 00045 00046 /** 00047 * \class WScriptInterpreterPython 00048 * 00049 * An interpreter for python scripts. 00050 */ 00051 class WScriptInterpreterPython : public WScriptInterpreter 00052 { 00053 public: 00054 /** 00055 * Constructor. Creates the interpreter. 00056 */ 00057 explicit WScriptInterpreterPython( boost::shared_ptr< WModuleContainer > const& rootContainer ); 00058 00059 /** 00060 * Destructor. Destroys the interpreter. 00061 */ 00062 virtual ~WScriptInterpreterPython(); 00063 00064 /** 00065 * Initializes bindings for OpenWalnut classes. Call this after starting the kernel. 00066 */ 00067 virtual void initBindings(); 00068 00069 /** 00070 * Sets the script parameters. These are the parameters you would normally call your script with, e.g. 00071 * "./myscript.py param 1 param2". 00072 * 00073 * \param params The parameters to the script. In our example, they would be "./myscript.py", "param", "1" and "param2". 00074 */ 00075 virtual void setParameters( std::vector< std::string > const& params ); 00076 00077 /** 00078 * Execute some python code. 00079 * 00080 * \param line The code to execute. 00081 */ 00082 virtual void execute( std::string const& line ); 00083 00084 /** 00085 * Execute a script in a seperate thread. This function returns immediately. 00086 * 00087 * \param script The script to execute. 00088 */ 00089 virtual void executeAsync( std::string const& script ); 00090 00091 /** 00092 * Execute a file. 00093 * 00094 * \param filename The script file to execute. 00095 */ 00096 virtual void executeFile( std::string const& filename ); 00097 00098 /** 00099 * Execute a script file in a seperate thread. This function returns immediately. 00100 * 00101 * \param filename The script file to execute. 00102 */ 00103 virtual void executeFileAsync( std::string const& filename ); 00104 00105 /** 00106 * Get the name of the language interpreted by this interpreter. 00107 * 00108 * \return The name of the script language. 00109 */ 00110 virtual std::string const getName() const; 00111 00112 /** 00113 * Get the default extension for script file belonging to the script interpreter's language. 00114 * 00115 * \return The default file extension. 00116 */ 00117 virtual std::string const getExtension() const; 00118 00119 private: 00120 /** 00121 * A thread that executes scripts from a queue. 00122 */ 00123 class ScriptThread : public WThreadedRunner 00124 { 00125 public: 00126 /** 00127 * Create a thread. 00128 */ 00129 explicit ScriptThread( WScriptInterpreterPython& interpreter ); // NOLINT reference 00130 00131 /** 00132 * Destructor. 00133 */ 00134 virtual ~ScriptThread(); 00135 00136 /** 00137 * Executes scripts stored in the script queue and sleeps as long as no 00138 * scripts are in the queue. 00139 */ 00140 virtual void threadMain(); 00141 00142 /** 00143 * Adds a script string to the queue. This is a thread-safe operation. 00144 * 00145 * \param script The script to add. 00146 */ 00147 void addToExecuteQueue( std::string const& script ); 00148 00149 /** 00150 * Request this script thread to stop. Returns immediatly. 00151 */ 00152 void requestStop(); 00153 00154 private: 00155 //! A queue for scripts to be executed. 00156 std::queue< std::string > m_scriptQueue; 00157 00158 //! A mutex for thread-safe adding to the queue. 00159 boost::mutex m_queueMutex; 00160 00161 //! A condition to be notified when a new script is added. 00162 boost::shared_ptr< WCondition > m_condition; 00163 00164 //! A condition set used for immidiate returns on wait() if it was notified beforehand. 00165 WConditionSet m_conditionSet; 00166 00167 //! A reference to the interpreter this thread belongs to. 00168 WScriptInterpreterPython& m_interpreter; 00169 }; 00170 00171 //! The python module. 00172 pb::object m_pyModule; 00173 00174 //! The namespace where we will be working. Bindings are declared in this workspace. 00175 pb::object m_pyMainNamespace; 00176 00177 //! A pointer to the kernel's root container. We can use this to manipulate modules. 00178 WModuleContainerWrapper m_rootContainer; 00179 00180 //! The logger. 00181 WLoggerWrapper m_logger; 00182 00183 //! The number of args passed when calling the script. 00184 int m_argc; 00185 00186 //! The args passed to the script. 00187 char** m_argv; 00188 00189 //! A mutex for safe execution of scripts. 00190 boost::mutex m_mutex; 00191 00192 //! A thread for asynchronous execution of scripts. 00193 ScriptThread m_scriptThread; 00194 }; 00195 00196 #endif // PYTHON_FOUND 00197 00198 #endif // WSCRIPTINTERPRETERPYTHON_H