itom 1.3.0
|
00001 /* ******************************************************************** 00002 itom software 00003 URL: http://www.uni-stuttgart.de/ito 00004 Copyright (C) 2013, Institut fuer Technische Optik (ITO), 00005 Universitaet Stuttgart, Germany 00006 00007 This file is part of itom. 00008 00009 itom is free software; you can redistribute it and/or modify it 00010 under the terms of the GNU Library General Public Licence as published by 00011 the Free Software Foundation; either version 2 of the Licence, or (at 00012 your option) any later version. 00013 00014 itom is distributed in the hope that it will be useful, but 00015 WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library 00017 General Public Licence for more details. 00018 00019 You should have received a copy of the GNU Library General Public License 00020 along with itom. If not, see <http://www.gnu.org/licenses/>. 00021 *********************************************************************** */ 00022 00023 #ifndef PYTHONENGINE_H 00024 #define PYTHONENGINE_H 00025 00026 /*if you add any include to this file you will DIE an immediate, horrible, painful death*/ 00027 00028 #include <string> 00029 //#ifndef Q_MOC_RUN 00030 // #define PY_ARRAY_UNIQUE_SYMBOL itom_ARRAY_API 00031 // #define NO_IMPORT_ARRAY 00032 //#endif 00033 00034 #ifndef ITOM_NPDATAOBJECT 00035 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION //see comment in pythonNpDataObject.cpp 00036 #endif 00037 00038 #ifndef Q_MOC_RUN 00039 //python 00040 // see http://vtk.org/gitweb?p=VTK.git;a=commitdiff;h=7f3f750596a105d48ea84ebfe1b1c4ca03e0bab3 00041 #if (defined _DEBUG) && (!defined linux) 00042 #undef _DEBUG 00043 #if (defined linux) | (defined CMAKE) 00044 #include "Python.h" 00045 #include "node.h" 00046 #include "numpy/arrayobject.h" 00047 #else 00048 #include "Python.h" 00049 #include "node.h" 00050 #include "../Lib/site-packages/numpy/core/include/numpy/arrayobject.h" //for numpy arrays 00051 #endif 00052 #define _DEBUG 00053 #else 00054 #ifdef linux 00055 #include "Python.h" 00056 #include "node.h" 00057 #include "numpy/arrayobject.h" 00058 #else 00059 #include "Python.h" 00060 #include "node.h" 00061 #include "../Lib/site-packages/numpy/core/include/numpy/arrayobject.h" //for numpy arrays 00062 #endif 00063 #endif 00064 #endif // Q_MOC_RUN 00065 00066 /* includes */ 00067 00068 #include "pythonNpDataObject.h" 00069 #include "pythonItom.h" 00070 00071 /* 00072 #ifdef linux 00073 #include "frameobject.h" 00074 #include "traceback.h" 00075 #else 00076 #include "include/frameobject.h" //!< for traceback 00077 #include "include/traceback.h" 00078 #endif 00079 */ 00080 00081 #include "../models/breakPointModel.h" 00082 #include "../../common/sharedStructuresQt.h" 00083 #include "../../common/addInInterface.h" 00084 00085 #include "pythonWorkspace.h" 00086 00087 #include <qstringlist.h> 00088 #include <qqueue.h> 00089 #include <qset.h> 00090 #include <qpointer.h> 00091 00092 00093 /* definition and macros */ 00094 00095 /* global variables (avoid) */ 00096 00097 /* content */ 00098 00099 class QDesktopWidget; 00100 class QTimer; 00101 00102 namespace ito 00103 { 00104 00105 class PythonEngine : public QObject 00106 { 00107 Q_OBJECT 00108 00109 public: 00110 PythonEngine(); //constructor 00111 ~PythonEngine(); //destructor 00112 00113 Q_INVOKABLE void pythonSetup(ito::RetVal *retValue); //setup 00114 Q_INVOKABLE ito::RetVal scanAndRunAutostartFolder(QString currentDirAfterScan = QString() ); 00115 Q_INVOKABLE ito::RetVal pythonShutdown(ItomSharedSemaphore *aimWait = NULL); //shutdown 00116 00117 Q_INVOKABLE ito::RetVal stringEncodingChanged(); 00118 00119 inline ito::BreakPointModel *getBreakPointModel() const { return bpModel; } 00120 inline bool isPythonBusy() const { return pythonState != ito::pyStateIdle; } 00121 inline bool isPythonDebugging() const { return (pythonState == ito::pyStateDebuggingWaitingButBusy || pythonState == ito::pyStateDebugging || pythonState == ito::pyStateDebuggingWaiting); } 00122 inline bool isPythonDebuggingAndWaiting() const { return pythonState == ito::pyStateDebuggingWaiting; } 00123 inline bool execInternalCodeByDebugger() const { return m_executeInternalPythonCodeInDebugMode; } 00124 inline void setExecInternalCodeByDebugger(bool value) { m_executeInternalPythonCodeInDebugMode = value; } 00125 00126 ito::RetVal checkForPyExceptions(); 00127 void printPythonErrorWithoutTraceback(); 00128 00129 void pythonDebugFunction(PyObject *callable, PyObject *argTuple); 00130 void pythonRunFunction(PyObject *callable, PyObject *argTuple); 00131 00132 inline PyObject *getGlobalDictionary() const { return globalDictionary; } 00134 inline bool pySyntaxCheckAvailable() const { return (m_pyModSyntaxCheck != NULL); } 00135 00136 static const PythonEngine *getInstance(); 00137 00138 QList<int> parseAndSplitCommandInMainComponents(const char *str, QByteArray &encoding) const; //can be directly called from different thread 00139 00140 protected: 00141 //RetVal syntaxCheck(char* pythonFileName); // syntaxCheck for file with filename pythonFileName 00142 ito::RetVal runPyFile(const QString &pythonFileName); // run file pythonFileName 00143 ito::RetVal debugFile(const QString &pythonFileName); // debug file pythonFileName 00144 ito::RetVal runString(const QString &command); // run string command 00145 ito::RetVal debugString(const QString &command); // debug string command 00146 ito::RetVal debugFunction(PyObject *callable, PyObject *argTuple); 00147 ito::RetVal runFunction(PyObject *callable, PyObject *argTuple); 00148 00149 ito::RetVal modifyTracebackDepth(int NrOfLevelsToPopAtFront = -1, bool showTraceback = true); 00150 00151 void connectNotify(const char* signal); 00152 00153 private: 00154 static PythonEngine *getInstanceInternal(); 00155 00156 inline PyObject *getLocalDictionary() { return localDictionary; } 00158 PyObject *getPyObjectByFullName(bool globalNotLocal, const QStringList &fullName); 00159 00160 void setGlobalDictionary(PyObject* mainDict = NULL); 00161 void setLocalDictionary(PyObject* localDict); 00162 00163 void emitPythonDictionary(bool emitGlobal, bool emitLocal, PyObject* globalDict, PyObject* localDict); 00164 00165 ito::RetVal pickleDictionary(PyObject *dict, const QString &filename); 00166 ito::RetVal unpickleDictionary(PyObject *destinationDict, const QString &filename, bool overwrite); 00167 00168 //methods for maintaining python functionality 00169 ito::RetVal addMethodToModule(PyMethodDef* def); 00170 ito::RetVal delMethodFromModule(const char* ml_name); 00171 ito::RetVal pythonAddBuiltinMethods(); 00172 00173 //methods for debugging 00174 void enqueueDbgCmd(ito::tPythonDbgCmd dbgCmd); 00175 ito::tPythonDbgCmd dequeueDbgCmd(); 00176 bool DbgCommandsAvailable(); 00177 void clearDbgCmdLoop(); 00178 00179 ito::RetVal pythonStateTransition(tPythonTransitions transition); 00180 00181 //methods for breakpoint 00182 ito::RetVal pythonAddBreakpoint(const QString &filename, const int lineno, const bool enabled, const bool temporary, const QString &condition, const int ignoreCount, int &pyBpNumber); 00183 ito::RetVal pythonEditBreakpoint(const int pyBpNumber, const QString &filename, const int lineno, const bool enabled, const bool temporary, const QString &condition, const int ignoreCount); 00184 ito::RetVal pythonDeleteBreakpoint(const int pyBpNumber); 00185 00186 ito::RetVal autoReloaderCheck(); 00187 00188 //member variables 00189 bool m_started; 00190 //QString m_itomMemberClasses; 00191 00192 //PyGILState_STATE threadState; 00193 00194 QMutex dbgCmdMutex; 00195 QMutex pythonStateChangeMutex; 00196 QMutex dictChangeMutex; 00197 QDesktopWidget *m_pDesktopWidget; 00198 QQueue<ito::tPythonDbgCmd> debugCommandQueue; 00199 ito::tPythonDbgCmd debugCommand; 00200 00201 ito::tPythonState pythonState; 00202 00203 ito::BreakPointModel *bpModel; 00204 00205 PyObject* mainModule; 00206 PyObject* mainDictionary; 00207 PyObject* localDictionary; 00208 PyObject* globalDictionary; 00209 PyObject *itomDbgModule; 00210 PyObject *itomDbgInstance; 00211 PyObject *itomModule; 00212 PyObject *itomFunctions; 00213 PyObject *m_pyModGC; 00214 PyObject *m_pyModSyntaxCheck; 00215 //PyObject *itomReturnException; //!< if this exception is thrown, the execution of the main application is stopped 00216 00217 PyObject *dictUnicode; 00218 00219 QSet<ito::PyWorkspaceContainer*> m_mainWorkspaceContainer; 00220 QSet<ito::PyWorkspaceContainer*> m_localWorkspaceContainer; 00221 QHash<QString, QPair<PyObject*,PyObject*> > m_pyFuncWeakRefHashes; 00222 int m_pyFuncWeakRefHashesAutoInc; 00223 bool m_executeInternalPythonCodeInDebugMode; 00224 PyMethodDef* PythonAdditionalModuleITOM; 00225 00226 // decides if itom is automatically included in every source file before itīs handed to the syntax checker 00227 bool m_includeItom; 00228 00229 struct AutoReload 00230 { 00231 PyObject *modAutoReload; 00232 PyObject *classAutoReload; 00233 bool enabled; 00234 bool checkFileExec; 00235 bool checkStringExec; 00236 bool checkFctExec; 00237 }; 00238 00239 AutoReload m_autoReload; 00240 00242 static PyMethodDef PyMethodItomDbg[]; 00243 static PyModuleDef PyModuleItomDbg; 00244 static PyObject* PyInitItomDbg(void); 00245 static PyObject* PyDbgCommandLoop(PyObject *pSelf, PyObject *pArgs); 00246 00247 //helper methods 00248 //static PyObject* checkForTimeoutHelper(ItomSharedSemaphore* semaphore, int timeout, PyObject *retValueOk); 00249 00250 //other static members 00251 static QMutex instatiated; 00252 static QMutex instancePtrProtection; 00253 00254 static PythonEngine* instance; 00255 00256 // friend class 00257 friend class ito::PythonItom; 00258 00259 signals: 00260 void pythonDebugPositionChanged(QString filename, int lineNo); 00261 void pythonStateChanged(tPythonTransitions pyTransition); 00262 void pythonModifyLocalDict(PyObject* localDict, ItomSharedSemaphore* semaphore); 00263 void pythonModifyGlobalDict(PyObject* globalDict, ItomSharedSemaphore* semaphore); 00264 void pythonAddToolbarButton(QString toolbarName, QString buttonName, QString buttonIconFilename, QString pythonCode); 00265 void pythonRemoveToolbarButton(QString toolbarName, QString buttonName); 00266 void pythonAddMenuElement(int typeID, QString key, QString name, QString code, QString icon); 00267 void pythonRemoveMenuElement(QString key); 00268 void pythonCurrentDirChanged(); 00269 void updateCallStack(QStringList filenames, IntList lines, QStringList methods); 00270 void deleteCallStack(); 00271 00272 void pythonSetCursor(const Qt::CursorShape cursor); 00273 void pythonResetCursor(); 00274 void pythonAutoReloadChanged(bool enabled, bool checkFile, bool checkCmd, bool checkFct); 00275 void clearCommandLine(); 00276 00277 public slots: 00278 void pythonRunString(QString cmd); 00279 void pythonDebugString(QString cmd); 00280 void pythonExecStringFromCommandLine(QString cmd); 00281 void pythonRunFile(QString filename); 00282 void pythonDebugFile(QString filename); 00283 void pythonRunStringOrFunction(QString cmdOrFctHash); 00284 void pythonDebugStringOrFunction(QString cmdOrFctHash); 00285 void pythonInterruptExecution() const; 00286 void pythonDebugCommand(tPythonDbgCmd cmd); 00287 00288 void setAutoReloader(bool enabled, bool checkFile, bool checkCmd, bool checkFct); 00289 00290 // Settings are neccesary for automatic itom inclusion and syntax check 00291 void readSettings(); 00292 void propertiesChanged(); 00293 00294 void pythonSyntaxCheck(const QString &code, QPointer<QObject> sender); 00295 00296 void pythonGenericSlot(PyObject* callable, PyObject *argumentTuple); 00297 00299 void breakPointAdded(BreakPointItem bp, int row); 00300 void breakPointDeleted(QString filename, int lineNo, int pyBpNumber); 00301 void breakPointChanged(BreakPointItem oldBp, BreakPointItem newBp); 00302 ito::RetVal setupBreakPointDebugConnections(); 00303 ito::RetVal shutdownBreakPointDebugConnections(); 00304 00305 bool renameVariable(bool globalNotLocal, QString oldKey, QString newKey, ItomSharedSemaphore *semaphore = NULL); 00306 bool deleteVariable(bool globalNotLocal, QStringList keys, ItomSharedSemaphore *semaphore = NULL); 00307 ito::RetVal pickleVariables(bool globalNotLocal, QString filename, QStringList varNames, ItomSharedSemaphore *semaphore = NULL); 00308 ito::RetVal unpickleVariables(bool globalNotLocal, QString filename, ItomSharedSemaphore *semaphore = NULL); 00309 ito::RetVal saveMatlabVariables(bool globalNotLocal, QString filename, QStringList varNames, ItomSharedSemaphore *semaphore = NULL); 00310 ito::RetVal loadMatlabVariables(bool globalNotLocal, QString filename, ItomSharedSemaphore *semaphore = NULL); 00311 ito::RetVal registerAddInInstance(QString varname, ito::AddInBase *instance, ItomSharedSemaphore *semaphore = NULL); 00312 ito::RetVal getSysModules(QSharedPointer<QStringList> modNames, QSharedPointer<QStringList> modFilenames, QSharedPointer<IntList> modTypes, ItomSharedSemaphore *semaphore = NULL); 00313 ito::RetVal reloadSysModules(QSharedPointer<QStringList> modNames, ItomSharedSemaphore *semaphore = NULL); 00314 00315 void registerWorkspaceContainer(PyWorkspaceContainer *container, bool registerNotUnregister, bool globalNotLocal); 00316 void workspaceGetChildNode(PyWorkspaceContainer *container, QString fullNameParentItem); 00317 void workspaceGetValueInformation(PyWorkspaceContainer *container, QString fullItemName, QSharedPointer<QString> extendedValue, ItomSharedSemaphore *semaphore = NULL); 00318 00319 void putParamsToWorkspace(bool globalNotLocal, QStringList names, QVector<SharedParamBasePointer > values, ItomSharedSemaphore *semaphore = NULL); 00320 void getParamsFromWorkspace(bool globalNotLocal, QStringList names, QVector<int> paramBaseTypes, QSharedPointer<SharedParamBasePointerVector > values, ItomSharedSemaphore *semaphore = NULL); 00321 00322 private slots: 00323 00324 }; 00325 00326 } //end namespace ito 00327 00328 00329 #endif