OpenWalnut  1.4.0
WScriptInterpreterPython.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WSCRIPTINTERPRETERPYTHON_H
26 #define WSCRIPTINTERPRETERPYTHON_H
27 
28 #ifdef PYTHON_FOUND
29 
30 #include <queue>
31 #include <string>
32 #include <vector>
33 
34 #include <boost/thread/mutex.hpp>
35 #include <boost/python.hpp>
36 
37 #include "../../common/WThreadedRunner.h"
38 
39 #include "../wrappers/WLoggerWrapper.h"
40 #include "../wrappers/WModuleContainerWrapper.h"
41 
42 #include "../WScriptInterpreter.h"
43 
44 namespace pb = boost::python;
45 
46 /**
47  * \class WScriptInterpreterPython
48  *
49  * An interpreter for python scripts.
50  */
51 class WScriptInterpreterPython : public WScriptInterpreter
52 {
53 public:
54  /**
55  * Constructor. Creates the interpreter.
56  */
57  explicit WScriptInterpreterPython( boost::shared_ptr< WModuleContainer > const& rootContainer );
58 
59  /**
60  * Destructor. Destroys the interpreter.
61  */
62  virtual ~WScriptInterpreterPython();
63 
64  /**
65  * Initializes bindings for OpenWalnut classes. Call this after starting the kernel.
66  */
67  virtual void initBindings();
68 
69  /**
70  * Sets the script parameters. These are the parameters you would normally call your script with, e.g.
71  * "./myscript.py param 1 param2".
72  *
73  * \param params The parameters to the script. In our example, they would be "./myscript.py", "param", "1" and "param2".
74  */
75  virtual void setParameters( std::vector< std::string > const& params );
76 
77  /**
78  * Execute some python code.
79  *
80  * \param line The code to execute.
81  */
82  virtual void execute( std::string const& line );
83 
84  /**
85  * Execute a script in a seperate thread. This function returns immediately.
86  *
87  * \param script The script to execute.
88  */
89  virtual void executeAsync( std::string const& script );
90 
91  /**
92  * Execute a file.
93  *
94  * \param filename The script file to execute.
95  */
96  virtual void executeFile( std::string const& filename );
97 
98  /**
99  * Execute a script file in a seperate thread. This function returns immediately.
100  *
101  * \param filename The script file to execute.
102  */
103  virtual void executeFileAsync( std::string const& filename );
104 
105  /**
106  * Get the name of the language interpreted by this interpreter.
107  *
108  * \return The name of the script language.
109  */
110  virtual std::string const getName() const;
111 
112  /**
113  * Get the default extension for script file belonging to the script interpreter's language.
114  *
115  * \return The default file extension.
116  */
117  virtual std::string const getExtension() const;
118 
119 private:
120  /**
121  * A thread that executes scripts from a queue.
122  */
123  class ScriptThread : public WThreadedRunner
124  {
125  public:
126  /**
127  * Create a thread.
128  */
129  explicit ScriptThread( WScriptInterpreterPython& interpreter ); // NOLINT reference
130 
131  /**
132  * Destructor.
133  */
134  virtual ~ScriptThread();
135 
136  /**
137  * Executes scripts stored in the script queue and sleeps as long as no
138  * scripts are in the queue.
139  */
140  virtual void threadMain();
141 
142  /**
143  * Adds a script string to the queue. This is a thread-safe operation.
144  *
145  * \param script The script to add.
146  */
147  void addToExecuteQueue( std::string const& script );
148 
149  /**
150  * Request this script thread to stop. Returns immediatly.
151  */
152  void requestStop();
153 
154  private:
155  //! A queue for scripts to be executed.
156  std::queue< std::string > m_scriptQueue;
157 
158  //! A mutex for thread-safe adding to the queue.
159  boost::mutex m_queueMutex;
160 
161  //! A condition to be notified when a new script is added.
162  boost::shared_ptr< WCondition > m_condition;
163 
164  //! A condition set used for immidiate returns on wait() if it was notified beforehand.
165  WConditionSet m_conditionSet;
166 
167  //! A reference to the interpreter this thread belongs to.
168  WScriptInterpreterPython& m_interpreter;
169  };
170 
171  //! The python module.
172  pb::object m_pyModule;
173 
174  //! The namespace where we will be working. Bindings are declared in this workspace.
175  pb::object m_pyMainNamespace;
176 
177  //! A pointer to the kernel's root container. We can use this to manipulate modules.
178  WModuleContainerWrapper m_rootContainer;
179 
180  //! The logger.
181  WLoggerWrapper m_logger;
182 
183  //! The number of args passed when calling the script.
184  int m_argc;
185 
186  //! The args passed to the script.
187  char** m_argv;
188 
189  //! A mutex for safe execution of scripts.
190  boost::mutex m_mutex;
191 
192  //! A thread for asynchronous execution of scripts.
193  ScriptThread m_scriptThread;
194 };
195 
196 #endif // PYTHON_FOUND
197 
198 #endif // WSCRIPTINTERPRETERPYTHON_H