From 7210239750af32d52b559b02a6a13298a3aba1aa Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 30 Dec 2016 08:11:58 +0100 Subject: [PATCH] First implementation --- src/LightApp/LightApp_Application.cxx | 7 +- src/SalomeApp/SalomeApp_Application.cxx | 2 +- src/SalomeApp/SalomeApp_PyInterp.cxx | 2 +- tools/PyConsole/src/PyConsole_Editor.cxx | 16 ++--- tools/PyConsole/src/PyConsole_Editor.h | 42 +++++------ tools/PyConsole/src/PyConsole_Interp.h | 5 +- tools/PyInterp/src/CMakeLists.txt | 1 + tools/PyInterp/src/PyInterp_Interp.h | 13 ++-- tools/PyInterp/src/PyInterp_RefCounterObj.h | 80 +++++++++++++++++++++ 9 files changed, 129 insertions(+), 39 deletions(-) create mode 100644 tools/PyInterp/src/PyInterp_RefCounterObj.h diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 37ca6fd0f..a019d5fb5 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -5145,17 +5145,18 @@ bool LightApp_Application::checkExistingDoc() PyConsole_Interp* LightApp_Application::getPyInterp() { - static PyConsole_Interp* myInterp = 0; - if ( !myInterp ) { + static PyInterp_Auto myInterp; + if ( myInterp.isNull() ) { myInterp = createPyInterp(); myInterp->initialize(); + myInterp->incrRef();// In Light application the PyConsole_Interp cannot been destroy. Why ? } return myInterp; } PyConsole_Interp* LightApp_Application::createPyInterp() { - return new PyConsole_Interp(); + return new PyConsole_Interp; } #endif // DISABLE_PYCONSOLE diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index fa6c6ab7b..e16d11d53 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -2082,7 +2082,7 @@ bool SalomeApp_Application::checkExistingDoc() PyConsole_Interp* SalomeApp_Application::createPyInterp() { - return new SalomeApp_PyInterp(); + return new SalomeApp_PyInterp; } #endif // DISABLE_PYCONSOLE diff --git a/src/SalomeApp/SalomeApp_PyInterp.cxx b/src/SalomeApp/SalomeApp_PyInterp.cxx index 0ab36f99a..4db5aff1a 100755 --- a/src/SalomeApp/SalomeApp_PyInterp.cxx +++ b/src/SalomeApp/SalomeApp_PyInterp.cxx @@ -28,7 +28,7 @@ \brief Constructor */ SalomeApp_PyInterp::SalomeApp_PyInterp() - : PyConsole_Interp(), myFirstRun( true ), myFirstInitStudy( false ) + : myFirstRun( true ), myFirstInitStudy( false ) { } diff --git a/tools/PyConsole/src/PyConsole_Editor.cxx b/tools/PyConsole/src/PyConsole_Editor.cxx index 7ec727292..4c3df75f0 100644 --- a/tools/PyConsole/src/PyConsole_Editor.cxx +++ b/tools/PyConsole/src/PyConsole_Editor.cxx @@ -155,9 +155,10 @@ void PyConsole_CallbackStderr( void* data, char* c ) PyConsole_Editor::PyConsole_Editor( QWidget* parent ) : QTextEdit( parent ) { - PyConsole_Interp* interp = new PyConsole_Interp(); + PyConsole_Interp *interp(new PyConsole_Interp); interp->initialize(); - init( interp ); + myInterp=interp; + init(); } /*! @@ -171,13 +172,13 @@ PyConsole_Editor::PyConsole_Editor( QWidget* parent, PyConsole_Interp* interp ) : QTextEdit( parent ) { - init( interp ); + myInterp.takeRef(interp); + init(); } -void PyConsole_Editor::init( PyConsole_Interp* interp ) +void PyConsole_Editor::init() { - myInterp = interp; myCmdInHistory = -1; myEventLoop = 0; myShowBanner = true; @@ -219,15 +220,14 @@ void PyConsole_Editor::init( PyConsole_Interp* interp ) */ PyConsole_Editor::~PyConsole_Editor() { - myInterp = 0; } /*! \brief Get Python interpreter */ -PyConsole_Interp* PyConsole_Editor::getInterp() const +PyConsole_Interp *PyConsole_Editor::getInterp() const { - return myInterp; + return myInterp.iAmATrollConstCast(); } /*! diff --git a/tools/PyConsole/src/PyConsole_Editor.h b/tools/PyConsole/src/PyConsole_Editor.h index 01c35c92e..cdf7078c7 100644 --- a/tools/PyConsole/src/PyConsole_Editor.h +++ b/tools/PyConsole/src/PyConsole_Editor.h @@ -27,6 +27,8 @@ #include "PyConsole.h" +#include "PyInterp_RefCounterObj.h" + #include #include @@ -96,7 +98,7 @@ protected: virtual QString getLogFileName(); private: - void init( PyConsole_Interp* ); + void init(); void multilinePaste( const QString& ); void multiLineProcessNextLine(); @@ -115,25 +117,25 @@ private: QString banner() const; inline int promptSize() const { return myPrompt.size(); } - PyConsole_Interp* myInterp; //!< python interpreter - QString myCommandBuffer; //!< python command buffer - QString myCurrentCommand; //!< currently being printed command - QString myPrompt; //!< current command line prompt - int myCmdInHistory; //!< current history command index - QString myLogFile; //!< current output log - QStringList myHistory; //!< commands history buffer - QEventLoop* myEventLoop; //!< internal event loop - bool myShowBanner; //!< 'show banner' flag - QStringList myQueue; //!< python commands queue - bool myIsSync; //!< synchronous mode flag - bool myIsSuppressOutput; //!< suppress output flag - bool myMultiLinePaste; //!< true when pasting several lines - QQueue myMultiLineContent; //!< queue of lines being pasted - bool myAutoCompletion; //!< auto-completion mode flag - bool myTabMode; //!< flag that is \c true when editor performs completion - QString myComplBeforePoint; //!< string on which the dir() command is executed - QString myComplAfterPoint; //!< string on which the results of the dir() are matched - int myComplCursorPos; //!< cursor position when is hit + PyInterp_Auto myInterp; //!< python interpreter + QString myCommandBuffer; //!< python command buffer + QString myCurrentCommand; //!< currently being printed command + QString myPrompt; //!< current command line prompt + int myCmdInHistory; //!< current history command index + QString myLogFile; //!< current output log + QStringList myHistory; //!< commands history buffer + QEventLoop* myEventLoop; //!< internal event loop + bool myShowBanner; //!< 'show banner' flag + QStringList myQueue; //!< python commands queue + bool myIsSync; //!< synchronous mode flag + bool myIsSuppressOutput; //!< suppress output flag + bool myMultiLinePaste; //!< true when pasting several lines + QQueue myMultiLineContent; //!< queue of lines being pasted + bool myAutoCompletion; //!< auto-completion mode flag + bool myTabMode; //!< flag that is \c true when editor performs completion + QString myComplBeforePoint; //!< string on which the dir() command is executed + QString myComplAfterPoint; //!< string on which the results of the dir() are matched + int myComplCursorPos; //!< cursor position when is hit friend void PyConsole_CallbackStdout( void*, char* ); friend void PyConsole_CallbackStderr( void*, char* ); diff --git a/tools/PyConsole/src/PyConsole_Interp.h b/tools/PyConsole/src/PyConsole_Interp.h index 4275c350f..434b73cd4 100644 --- a/tools/PyConsole/src/PyConsole_Interp.h +++ b/tools/PyConsole/src/PyConsole_Interp.h @@ -36,11 +36,14 @@ class PYCONSOLE_EXPORT PyConsole_Interp : public PyInterp_Interp public: PyConsole_Interp(); - ~PyConsole_Interp(); virtual int afterRun(); virtual int beforeRun(); +protected: + + ~PyConsole_Interp(); + private: bool runDirCommand( const QString&, const QString&, QStringList&, QString& ); bool runDirAndExtract( const QString&, const QString&, QStringList&, bool = true ) const; diff --git a/tools/PyInterp/src/CMakeLists.txt b/tools/PyInterp/src/CMakeLists.txt index c29e7e5fd..392246b87 100755 --- a/tools/PyInterp/src/CMakeLists.txt +++ b/tools/PyInterp/src/CMakeLists.txt @@ -47,6 +47,7 @@ SET(_other_HEADERS PyInterp_Interp.h PyInterp_Request.h PyInterp_Utils.h + PyInterp_RefCounterObj.h ) # header files / to install diff --git a/tools/PyInterp/src/PyInterp_Interp.h b/tools/PyInterp/src/PyInterp_Interp.h index 88e551916..b7855434b 100644 --- a/tools/PyInterp/src/PyInterp_Interp.h +++ b/tools/PyInterp/src/PyInterp_Interp.h @@ -27,6 +27,7 @@ #include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! #include "PyInterp_Utils.h" +#include "PyInterp_RefCounterObj.h" #include #include @@ -50,20 +51,17 @@ typedef struct { * (only there namespace is made available when importing in another context). * See also class PyConsole_Interp. */ -class PYINTERP_EXPORT PyInterp_Interp +class PYINTERP_EXPORT PyInterp_Interp : public PyInterp_RefCounterObj { public: static int _argc; static char* _argv[]; - PyInterp_Interp(); - virtual ~PyInterp_Interp(); - void initialize(); void destroy(); virtual int run(const char *command); - virtual void initStudy() {}; + virtual void initStudy() {} std::string getBanner() const; void setverrcb(PyOutChanged*, void*); @@ -72,6 +70,11 @@ public: const char* getPrevious(); const char* getNext(); +protected: + + PyInterp_Interp(); + virtual ~PyInterp_Interp(); + protected: /** Redirection of stdout and stderr */ PyObject* _vout; diff --git a/tools/PyInterp/src/PyInterp_RefCounterObj.h b/tools/PyInterp/src/PyInterp_RefCounterObj.h new file mode 100644 index 000000000..b251b090c --- /dev/null +++ b/tools/PyInterp/src/PyInterp_RefCounterObj.h @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : PyInterp_RefCounterObj.h +// Author : Anthony Geay (EDF R&D) + +#ifndef PYINTERP_REFCOUNTEROBJ_H +#define PYINTERP_REFCOUNTEROBJ_H + +#include "PyInterp.h" + +template +class PYINTERP_EXPORT PyInterp_Auto +{ +public: + PyInterp_Auto(const PyInterp_Auto& other):_ptr(0) { referPtr(other._ptr); } + PyInterp_Auto(T *ptr=0):_ptr(ptr) { } + ~PyInterp_Auto() { destroyPtr(); } + bool isNull() const { return _ptr==0; } + bool isNotNull() const { return !isNull(); } + void nullify() { destroyPtr(); _ptr=0; } + bool operator==(const PyInterp_Auto& other) const { return _ptr==other._ptr; } + bool operator==(const T *other) const { return _ptr==other; } + PyInterp_Auto &operator=(const PyInterp_Auto& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; } + PyInterp_Auto &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; } + void takeRef(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; if(_ptr) _ptr->incrRef(); } } + T *operator->() { return _ptr ; } + const T *operator->() const { return _ptr; } + T& operator*() { return *_ptr; } + const T& operator*() const { return *_ptr; } + operator T *() { return _ptr; } + operator const T *() const { return _ptr; } + T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; } + T *iAmATrollConstCast() const { return _ptr; } + private: + void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); } + void destroyPtr() { if(_ptr) _ptr->decrRef(); } + private: + T *_ptr; +}; + +class PYINTERP_EXPORT PyInterp_RefCounterObj +{ + protected: + PyInterp_RefCounterObj():_cnt(1) { } + PyInterp_RefCounterObj(const PyInterp_RefCounterObj& other):_cnt(1) { } + public: + bool decrRef() const + { + bool ret=((--_cnt)==0); + if(ret) + delete this; + return ret; + } + void incrRef() const { _cnt++; } + int getRCValue() const { return _cnt; } + // copies using operator= should not copy the ref counter of \a other + PyInterp_RefCounterObj& operator=(const PyInterp_RefCounterObj& other) { return *this; } + protected: + virtual ~PyInterp_RefCounterObj() { } + private: + mutable int _cnt; +}; + +#endif // PYINTERP_REFCOUNTEROBJ_H -- 2.39.2