29 #include "core/kernel/WKernel.h"
31 #include "../wrappers/WLoggerWrapper.h"
32 #include "../wrappers/WModuleWrapper.h"
33 #include "../wrappers/WPropertyGroupWrapper.h"
34 #include "../wrappers/WPropertyWrapper.h"
36 #include "WScriptInterpreterPython.h"
40 WScriptInterpreterPython::WScriptInterpreterPython( boost::shared_ptr< WModuleContainer >
const& rootContainer )
42 m_rootContainer( rootContainer ),
45 m_scriptThread( *this )
50 m_pyModule = pb::import(
"__main__" );
51 m_pyMainNamespace = m_pyModule.attr(
"__dict__" );
53 catch( pb::error_already_set
const& )
59 execute(
"signal.signal( signal.SIGINT, signal.SIG_DFL )" );
64 WScriptInterpreterPython::~WScriptInterpreterPython()
66 m_scriptThread.requestStop();
67 m_scriptThread.wait();
73 for(
int k = 0; k < m_argc; ++k )
81 void WScriptInterpreterPython::initBindings()
83 boost::unique_lock< boost::mutex > lock( m_mutex );
87 m_pyMainNamespace[
"WProperty" ] = pb::class_< WPropertyWrapper >(
"WProperty", pb::no_init )
105 m_pyMainNamespace[
"WPropertyGroup" ] = pb::class_< WPropertyGroupWrapper >(
"WPropertyGroup", pb::no_init )
111 m_pyMainNamespace[
"WModuleContainer" ] = pb::class_< WModuleContainerWrapper >(
"WModuleContainer", pb::no_init )
116 m_pyMainNamespace[
"WOutputConnector" ] = pb::class_< WOutputConnectorWrapper >(
"WOutputConnectorWrapper", pb::no_init )
119 m_pyMainNamespace[
"WInputConnector" ] = pb::class_< WInputConnectorWrapper >(
"WInputConnectorWrapper", pb::no_init )
124 m_pyMainNamespace[
"WModule" ] = pb::class_< WModuleWrapper >(
"WModule", pb::no_init )
134 m_pyMainNamespace[
"rootContainer" ] = &m_rootContainer;
136 m_pyMainNamespace[
"WLogger" ] = pb::class_< WLoggerWrapper >(
"WLogger", pb::no_init )
142 m_pyMainNamespace[
"logger" ] = &m_logger;
145 void WScriptInterpreterPython::setParameters( std::vector< std::string >
const& params )
147 boost::unique_lock< boost::mutex > lock( m_mutex );
149 if( params.size() == 0 )
154 m_argc = params.size();
155 m_argv =
new char*[ params.size() ];
157 for( std::size_t k = 0; k < params.size(); ++k )
159 m_argv[ k ] =
new char[ params[ k ].length() + 1 ];
160 std::snprintf( m_argv[ k ], params[ k ].length() + 1,
"%s", params[ k ].c_str() );
161 m_argv[ k ][ params[ k ].length() ] =
'\0';
164 PySys_SetArgv( m_argc, m_argv );
167 void WScriptInterpreterPython::execute( std::string
const& line )
169 boost::unique_lock< boost::mutex > lock( m_mutex );
173 pb::exec( line.c_str(), m_pyMainNamespace );
175 catch( pb::error_already_set
const& )
181 void WScriptInterpreterPython::executeAsync( std::string
const& script )
183 m_scriptThread.addToExecuteQueue( script );
186 void WScriptInterpreterPython::executeFile( std::string
const& filename )
189 std::ifstream in( filename.c_str() );
192 while( std::getline( in, line ) )
194 script += line +
"\n";
205 wlog::error(
"Walnut" ) <<
"Error while executing script: " << e.
what();
209 void WScriptInterpreterPython::executeFileAsync( std::string
const& filename )
212 std::ifstream in( filename.c_str() );
215 while( std::getline( in, line ) )
217 script += line +
"\n";
222 executeAsync( script );
225 std::string
const WScriptInterpreterPython::getName()
const
230 std::string
const WScriptInterpreterPython::getExtension()
const
235 WScriptInterpreterPython::ScriptThread::ScriptThread( WScriptInterpreterPython& interpreter )
241 m_interpreter( interpreter )
243 m_conditionSet.setResetable(
true,
true );
244 m_conditionSet.add( m_condition );
247 WScriptInterpreterPython::ScriptThread::~ScriptThread()
251 void WScriptInterpreterPython::ScriptThread::requestStop()
254 m_condition->notify();
257 void WScriptInterpreterPython::ScriptThread::threadMain()
259 while( !m_shutdownFlag )
261 m_conditionSet.wait();
266 std::size_t numScripts = 0;
268 boost::unique_lock< boost::mutex > lock( m_queueMutex );
269 numScripts = m_scriptQueue.size();
272 while( numScripts > 0 )
278 boost::unique_lock< boost::mutex > lock( m_queueMutex );
279 script = m_scriptQueue.front();
283 if( script.length() != 0 )
285 wlog::info(
"WScriptInterpreterPython::ScriptThread" ) <<
"Executing script asyncronously.";
287 m_interpreter.execute( script );
288 wlog::info(
"WScriptInterpreterPython::ScriptThread" ) <<
"Done executing script.";
291 boost::unique_lock< boost::mutex > lock( m_queueMutex );
292 numScripts = m_scriptQueue.size();
298 void WScriptInterpreterPython::ScriptThread::addToExecuteQueue( std::string
const& script )
300 wlog::info(
"WScriptInterpreterPython::ScriptThread" ) <<
"Queueing script for asyncronous execution.";
302 boost::unique_lock< boost::mutex > lock( m_queueMutex );
303 m_scriptQueue.push( script );
304 m_condition->notify();
307 #endif // PYTHON_FOUND
WStreamedLogger error(const std::string &source)
Logging an error message.
void setFilename(std::string const &fn)
Set the filename of the filename property.
void disconnect()
Disconnect this connector.
void remove(WModuleWrapper module)
Remove a module from the container.
bool getBool(bool notify=false) const
Get the value of a boolean property.
void waitForUpdate()
Wait for the property to update its value.
void setString(std::string const &s)
Set the value of a string property.
WStreamedLogger info(const std::string &source)
Logging an information message.
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
WPropertyGroupWrapper getProperties()
Returns a WPropertyGroupWrapper containing the module's properties.
virtual void execute(std::string const &line)=0
Execute some code.
WModuleWrapper create(std::string const &name)
Creates a module from the prototype with the given name.
void setDouble(double d)
Set the value of a double property.
void setBool(bool b)
Set the value of a boolean property.
Base class for all classes needing to be executed in a separate thread.
WPropertyGroupWrapper getGroup(std::string const &name)
Retrieve a property group by name.
std::string getName() const
Get the name of the module.
void setSelection(int s)
Sets the selected item of a selection.
An abstract base class for a script interpreter.
bool removeFileStream(std::string filename)
Remove a file to which the logger writes.
std::string getDescription() const
Get the description of the module.
std::string getDescription() const
Return the description of the property.
WPropertyGroupWrapper getInformationProperties()
Returns a WPropertyGroupWrapper containing the module's info properties.
std::string getString(bool notify=false) const
Get the value of a string property.
double getDouble(bool notify=false) const
Get the value of a double property.
std::string getName() const
Return the name of the property group.
void click()
Trigger a trigger property.
int getSelection(bool notify=false) const
Get the (first) selected item of a selection property.
WOutputConnectorWrapper getOutputConnector(std::string const &name)
Get an output connector by name.
Class to encapsulate boost::condition_variable_any.
virtual const char * what() const
Returns the message string set on throw.
WPropertyWrapper getProperty(std::string const &name)
Retrieve a property by name.
virtual void requestStop()
This method's purpose is to request a stop without waiting for it.
std::string getName() const
Return the name of the property.
void setInt(int i)
Set the value of an integer property.
std::string getFilename(bool notify=false) const
Get the filename of a filename property.
void removeAllFileStreams()
Remove all files to which the logger writes (and which were added by this wrapper).
bool addFileStream(std::string filename)
Add a file to which the logger output will be written.
WInputConnectorWrapper getInputConnector(std::string const &name)
Get an input connector by name.
WModuleWrapper createDataModule(std::string const &filename)
Creates a data module and load the file given via filename.
int getInt(bool notify=false) const
Get the value of an integer property.
std::string getDescription() const
Return the description of the property group.