itom 1.0.14
|
00001 /* ******************************************************************** 00002 itom software 00003 URL: http://www.uni-stuttgart.de/ito 00004 Copyright (C) 2013, Institut für Technische Optik (ITO), 00005 Universität 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 //#define NPY_NO_DEPRECATED_API 0x00000007 //see comment in pythonNpDataObject.cpp 00035 00036 //python 00037 // see http://vtk.org/gitweb?p=VTK.git;a=commitdiff;h=7f3f750596a105d48ea84ebfe1b1c4ca03e0bab3 00038 #ifdef _DEBUG 00039 #undef _DEBUG 00040 #if (defined linux) | (defined CMAKE) 00041 #include "Python.h" 00042 #include "node.h" 00043 #include "numpy/arrayobject.h" 00044 #else 00045 #include "Python.h" 00046 #include "node.h" 00047 #include "../Lib/site-packages/numpy/core/include/numpy/arrayobject.h" //for numpy arrays 00048 #endif 00049 #define _DEBUG 00050 #else 00051 #ifdef linux 00052 #include "Python.h" 00053 #include "node.h" 00054 #include "numpy/arrayobject.h" 00055 #else 00056 #include "Python.h" 00057 #include "node.h" 00058 #include "../Lib/site-packages/numpy/core/include/numpy/arrayobject.h" //for numpy arrays 00059 #endif 00060 #endif 00061 00062 /* includes */ 00063 00064 #include "pythonNpDataObject.h" 00065 #include "pythonItom.h" 00066 00067 /* 00068 #ifdef linux 00069 #include "frameobject.h" 00070 #include "traceback.h" 00071 #else 00072 #include "include/frameobject.h" //!< for traceback 00073 #include "include/traceback.h" 00074 #endif 00075 */ 00076 00077 #include "../models/breakPointModel.h" 00078 #include "../../common/sharedStructuresQt.h" 00079 #include "../../common/addInInterface.h" 00080 00081 #include "pythonWorkspace.h" 00082 00083 #include <qstringlist.h> 00084 #include <qqueue.h> 00085 #include <qset.h> 00086 00087 00088 /* definition and macros */ 00089 00090 /* global variables (avoid) */ 00091 00092 /* content */ 00093 00094 class QDesktopWidget; 00095 class QTimer; 00096 00097 class PythonEngine : public QObject 00098 { 00099 Q_OBJECT 00100 00101 public: 00102 PythonEngine(); //constructor 00103 ~PythonEngine(); //destructor 00104 00105 Q_INVOKABLE void pythonSetup(ito::RetVal *retValue); //setup 00106 Q_INVOKABLE ito::RetVal scanAndRunAutostartFolder(QString currentDirAfterScan = QString() ); 00107 Q_INVOKABLE ito::RetVal pythonShutdown(ItomSharedSemaphore *aimWait = NULL); //shutdown 00108 00109 Q_INVOKABLE ito::RetVal stringEncodingChanged(); 00110 00111 inline BreakPointModel *getBreakPointModel() const { return bpModel; } 00112 inline bool isPythonBusy() const { return pythonState != pyStateIdle; } 00113 inline bool isPythonDebugging() const { return (pythonState == pyStateDebuggingWaitingButBusy || pythonState == pyStateDebugging || pythonState == pyStateDebuggingWaiting); } 00114 inline bool isPythonDebuggingAndWaiting() const { return pythonState == pyStateDebuggingWaiting; } 00115 inline bool execInternalCodeByDebugger() const { return m_executeInternalPythonCodeInDebugMode; } 00116 inline void setExecInternalCodeByDebugger(bool value) { m_executeInternalPythonCodeInDebugMode = value; } 00117 00118 ito::RetVal checkForPyExceptions(); 00119 void printPythonErrorWithoutTraceback(); 00120 00121 void pythonDebugFunction(PyObject *callable, PyObject *argTuple); 00122 void pythonRunFunction(PyObject *callable, PyObject *argTuple); 00123 00124 inline PyObject *getGlobalDictionary() { return globalDictionary; } 00126 static const PythonEngine *getInstance(); 00127 00128 QList<int> parseAndSplitCommandInMainComponents(const char *str, QByteArray &encoding) const; //can be directly called from different thread 00129 00130 protected: 00131 RetVal syntaxCheck(char* pythonFileName); // syntaxCheck for file with filename pythonFileName 00132 RetVal runPyFile(char* pythonFileName); // run file pythonFileName 00133 RetVal debugFile(char* pythonFileName); // debug file pythonFileName 00134 RetVal runString(const char *command); // run string command 00135 RetVal debugString(const char *command); // debug string command 00136 RetVal debugFunction(PyObject *callable, PyObject *argTuple); 00137 RetVal runFunction(PyObject *callable, PyObject *argTuple); 00138 00139 RetVal modifyTracebackDepth(int NrOfLevelsToPopAtFront = -1, bool showTraceback = true); 00140 00141 private: 00142 static PythonEngine *getInstanceInternal(); 00143 00144 inline PyObject *getLocalDictionary() { return localDictionary; } 00146 PyObject *getPyObjectByFullName(bool globalNotLocal, QStringList &fullName); 00147 00148 void setGlobalDictionary(PyObject* mainDict = NULL); 00149 void setLocalDictionary(PyObject* localDict); 00150 00151 void emitPythonDictionary(bool emitGlobal, bool emitLocal, PyObject* globalDict, PyObject* localDict); 00152 00153 RetVal pickleDictionary(PyObject *dict, QString filename); 00154 RetVal unpickleDictionary(PyObject *destinationDict, QString filename, bool overwrite); 00155 RetVal saveDictAsMatlab(PyObject *dict, QString filename); 00156 RetVal loadMatlabToDict(PyObject *destinationDict, QString filename); 00157 00158 //methods for maintaining python functionality 00159 RetVal addMethodToModule(PyMethodDef* def); 00160 RetVal delMethodFromModule(const char* ml_name); 00161 RetVal pythonAddBuiltinMethods(); 00162 00163 //methods for debugging 00164 void enqueueDbgCmd(tPythonDbgCmd dbgCmd); 00165 tPythonDbgCmd dequeueDbgCmd(); 00166 bool DbgCommandsAvailable(); 00167 void clearDbgCmdLoop(); 00168 00169 RetVal pythonStateTransition(tPythonTransitions transition); 00170 00171 //methods for breakpoint 00172 RetVal pythonAddBreakpoint(const QString &filename, const int lineno, const bool enabled, const bool temporary, const QString &condition, const int ignoreCount, int &pyBpNumber); 00173 RetVal pythonEditBreakpoint(const int pyBpNumber, const QString &filename, const int lineno, const bool enabled, const bool temporary, const QString &condition, const int ignoreCount); 00174 RetVal pythonDeleteBreakpoint(const int pyBpNumber); 00175 00176 //member variables 00177 bool started; 00178 00179 //PyGILState_STATE threadState; 00180 00181 QMutex dbgCmdMutex; 00182 QMutex pythonStateChangeMutex; 00183 QMutex dictChangeMutex; 00184 QDesktopWidget *m_pDesktopWidget; 00185 QQueue<tPythonDbgCmd> debugCommandQueue; 00186 tPythonDbgCmd debugCommand; 00187 00188 tPythonState pythonState; 00189 00190 BreakPointModel *bpModel; 00191 00192 PyObject* mainModule; 00193 PyObject* mainDictionary; 00194 PyObject* localDictionary; 00195 PyObject* globalDictionary; 00196 PyObject *itomDbgModule; 00197 PyObject *itomDbgInstance; 00198 PyObject *itomModule; 00199 PyObject *itomFunctions; 00200 PyObject *gcModule; 00201 //PyObject *itomReturnException; //!< if this exception is thrown, the execution of the main application is stopped 00202 00203 PyObject *dictUnicode; 00204 00205 QSet<PyWorkspaceContainer*> m_mainWorkspaceContainer; 00206 QSet<PyWorkspaceContainer*> m_localWorkspaceContainer; 00207 QHash<QString, QPair<PyObject*,PyObject*> > m_pyFuncWeakRefHashes; 00208 int m_pyFuncWeakRefHashesAutoInc; 00209 bool m_executeInternalPythonCodeInDebugMode; 00210 PyMethodDef* PythonAdditionalModuleITOM; 00211 00213 static PyMethodDef PyMethodItomDbg[]; 00214 static PyModuleDef PyModuleItomDbg; 00215 static PyObject* PyInitItomDbg(void); 00216 static PyObject* PyDbgCommandLoop(PyObject *pSelf, PyObject *pArgs); 00217 00218 //helper methods 00219 //static PyObject* checkForTimeoutHelper(ItomSharedSemaphore* semaphore, int timeout, PyObject *retValueOk); 00220 00221 //other static members 00222 static QMutex instatiated; 00223 static QMutex instancePtrProtection; 00224 00225 static PythonEngine* instance; 00226 00227 // friend class 00228 friend class PythonDataObject; 00229 friend class ito::PythonItom; 00230 00231 signals: 00232 void pythonDebugPositionChanged(QString filename, int lineNo); 00233 void pythonStateChanged(tPythonTransitions pyTransition); 00234 void pythonModifyLocalDict(PyObject* localDict, ItomSharedSemaphore* semaphore); 00235 void pythonModifyGlobalDict(PyObject* globalDict, ItomSharedSemaphore* semaphore); 00236 void pythonAddToolbarButton(QString toolbarName, QString buttonName, QString buttonIconFilename, QString pythonCode); 00237 void pythonRemoveToolbarButton(QString toolbarName, QString buttonName); 00238 void pythonAddMenuElement(int typeID, QString key, QString name, QString code, QString icon); 00239 void pythonRemoveMenuElement(QString key); 00240 void pythonCurrentDirChanged(); 00241 void updateCallStack(QStringList filenames, IntList lines, QStringList methods); 00242 void deleteCallStack(); 00243 00244 void pythonSetCursor(const Qt::CursorShape cursor); 00245 void pythonResetCursor(); 00246 00247 public slots: 00248 void pythonRunString(QString cmd); 00249 void pythonDebugString(QString cmd); 00250 void pythonExecStringFromCommandLine(QString cmd); 00251 void pythonRunFile(QString filename); 00252 void pythonDebugFile(QString filename); 00253 void pythonRunStringOrFunction(QString cmdOrFctHash); 00254 void pythonDebugStringOrFunction(QString cmdOrFctHash); 00255 void pythonInterruptExecution() const; 00256 void pythonDebugCommand(tPythonDbgCmd cmd); 00257 00258 void pythonGenericSlot(PyObject* callable, PyObject *argumentTuple); 00259 00261 void breakPointAdded(BreakPointItem bp, int row); 00262 void breakPointDeleted(QString filename, int lineNo, int pyBpNumber); 00263 void breakPointChanged(BreakPointItem oldBp, BreakPointItem newBp); 00264 RetVal setupBreakPointDebugConnections(); 00265 RetVal shutdownBreakPointDebugConnections(); 00266 00267 bool renameVariable(bool globalNotLocal, QString oldKey, QString newKey, ItomSharedSemaphore *semaphore = NULL); 00268 bool deleteVariable(bool globalNotLocal, QStringList keys, ItomSharedSemaphore *semaphore = NULL); 00269 RetVal pickleVariables(bool globalNotLocal, QString filename, QStringList varNames, ItomSharedSemaphore *semaphore = NULL); 00270 RetVal unpickleVariables(bool globalNotLocal, QString filename, ItomSharedSemaphore *semaphore = NULL); 00271 RetVal saveMatlabVariables(bool globalNotLocal, QString filename, QStringList varNames, ItomSharedSemaphore *semaphore = NULL); 00272 RetVal loadMatlabVariables(bool globalNotLocal, QString filename, ItomSharedSemaphore *semaphore = NULL); 00273 RetVal registerAddInInstance(QString varname, ito::AddInBase *instance, ItomSharedSemaphore *semaphore = NULL); 00274 RetVal getSysModules(QSharedPointer<QStringList> modNames, QSharedPointer<QStringList> modFilenames, QSharedPointer<IntList> modTypes, ItomSharedSemaphore *semaphore = NULL); 00275 RetVal reloadSysModules(QSharedPointer<QStringList> modNames, ItomSharedSemaphore *semaphore = NULL); 00276 00277 void registerWorkspaceContainer(PyWorkspaceContainer *container, bool registerNotUnregister, bool globalNotLocal); 00278 void workspaceGetChildNode(ito::PyWorkspaceContainer *container, QString fullNameParentItem); 00279 void workspaceGetValueInformation(PyWorkspaceContainer *container, QString fullItemName, QSharedPointer<QString> extendedValue, ItomSharedSemaphore *semaphore = NULL); 00280 00281 void putParamsToWorkspace(bool globalNotLocal, QStringList names, QVector<SharedParamBasePointer > values, ItomSharedSemaphore *semaphore = NULL); 00282 void getParamsFromWorkspace(bool globalNotLocal, QStringList names, QVector<int> paramBaseTypes, QSharedPointer<SharedParamBasePointerVector > values, ItomSharedSemaphore *semaphore = NULL); 00283 00284 private slots: 00285 00286 }; 00287 00288 00289 #endif