]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
SALOME_Event ideology changed
authorsmh <smh@opencascade.com>
Thu, 1 Apr 2004 13:12:39 +0000 (13:12 +0000)
committersmh <smh@opencascade.com>
Thu, 1 Apr 2004 13:12:39 +0000 (13:12 +0000)
src/Event/SALOME_Event.cxx
src/Event/SALOME_Event.hxx
src/SALOMEGUI/QAD_Desktop.cxx
src/SALOMEGUI/QAD_Desktop.h
src/SALOMEGUI/SALOMEGUI_Swig.cxx
src/SALOMEGUI/SALOMEGUI_Swig.hxx
src/SALOMEGUI/SALOMEGUI_Swig.i

index 36ec6ce99ec4fbfadeb115ee4070c47c63612c34..f40251e3a0edb34527aeacb643d4d0814398d729 100644 (file)
-// File:       SALOME_Event.cxx
-// Created:    Tue Mar 30 15:06:32 2004
-// Author:     Sergey ANIKIN
-//             <san@startrex.nnov.opencascade.com>
-
+//  KERNEL SALOME_Event : Define event posting mechanism
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  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. 
+// 
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SALOME_Event.cxx
+//  Author : Sergey ANIKIN
+//  Module : KERNEL
+//  $Header$
 
 #include "SALOME_Event.hxx"
 
 #include "utilities.h"
 
-//===========================================================================
-// ~SALOME_Semaphore
-//===========================================================================
-SALOME_Semaphore::~SALOME_Semaphore()
+#include <qsemaphore.h>
+#include <qapplication.h>
+#include <qthread.h>
+
+//===========================================================
+/*!
+ *  SALOME_Event::SALOME_Event
+ *  Constructor
+ */
+//===========================================================
+SALOME_Event::SALOME_Event( int salomeEventType, bool wait )
+: myType( salomeEventType ), 
+  myWait( wait )
+{
+  MESSAGE( "SALOME_Event::SALOME_Event(): myType = "<<myType<<", myWait = "<<myWait );
+  if ( wait ) {
+    // Prepare the semaphore 
+    mySemaphore = new QSemaphore( 1 );
+    mySemaphore->operator++( 1 );
+  }
+}
+
+//===========================================================
+/*!
+ *  SALOME_Event::~SALOME_Event
+ *  Destructor
+ */
+//===========================================================
+SALOME_Event::~SALOME_Event()
 {
+  MESSAGE( "SALOME_Event::~SALOME_Event(): myType = "<<myType<<", myWait = "<<myWait );
+  if ( myWait ) {
+    if ( mySemaphore->available() < mySemaphore->total() )
+      mySemaphore->operator-=( mySemaphore->total() - mySemaphore->available() );
+    delete mySemaphore;
+  }
 }
 
-//===========================================================================
-// SALOME_Event
-//===========================================================================
-SALOME_Event::SALOME_Event( int salomeEventType, SALOME_Semaphore* s )
-: QCustomEvent( (QEvent::Type)(QEvent::User + 1), (void*)s ), 
-  myType( salomeEventType )
+//===========================================================
+/*!
+ *  SALOME_Event::process
+ *  Posts the event and optionally waits for its completion
+ */
+//===========================================================
+void SALOME_Event::process()
 {
-  MESSAGE( "SALOME_Event::SALOME_Event(): type = " << myType << ", semaphore = " << s );
-  if ( s ) {
-    MESSAGE( "SALOME_Event::SALOME_Event(): available = " << s->available() );
-    ASSERT( s->available() == 1 );
-    s->operator++( 1 );
+  MESSAGE( "SALOME_Event::process(): myType = "<<myType<<",myWait = "<<myWait );
+  QThread::postEvent( qApp, new QCustomEvent( SALOME_EVENT, (void*)this ) );
+  if ( myWait ) {
+    MESSAGE( "SALOME_Event::process(): available = " << mySemaphore->available() );
+    if ( !mySemaphore->available() )
+      mySemaphore->operator++( 1 );
+
+    MESSAGE( "SALOME_Event::process() COMPLETED: myType = "<<myType<<",myWait = "<<myWait );
+
+    // processed() waits for this loop to complete
+    while ( mySemaphore->available() < mySemaphore->total() )
+      mySemaphore->operator--( 1 );
   }
 }
 
-//===========================================================================
-// processed
-//===========================================================================
+//===========================================================
+/*!
+ *  SALOME_Event::processed
+ *  Signals that this event has been processsed
+ */
+//===========================================================
 void SALOME_Event::processed()
 {
-  MESSAGE( "SALOME_Event::processed()" );
-  if ( getSemaphore() && !getSemaphore()->available() ) {
-    MESSAGE( "SALOME_Event::SALOME_Event(): available = " << getSemaphore()->available() );
-    getSemaphore()->operator--( 1 );
+  MESSAGE( "SALOME_Event::processed(): myType = "<<myType<<",myWait = "<<myWait );
+  if ( myWait ) {
+    MESSAGE( "SALOME_Event::processed(): available = " << mySemaphore->available() );
+    if ( !mySemaphore->available() )
+      // process() takes control over mySemaphore after the next line is executed
+      mySemaphore->operator--( 1 );
+
+    // Current thread will block here until process() completes
+    mySemaphore->operator+=( mySemaphore->total() );
   }
+  MESSAGE( "SALOME_Event::processed() COMPLETED: myType = "<<myType<<",myWait = "<<myWait );
 }
 
 
index 2e0df31c942a2c5e4264fd54aa57ae3ee028276d..724bb28b9dc7babff2b67c2d00800fddc5cf8543 100644 (file)
@@ -1,35 +1,91 @@
-// File:       SALOME_Event.hxx
-// Created:    Mon Mar 29 16:36:52 2004
-// Author:     Sergey ANIKIN
-//             <san@startrex.nnov.opencascade.com>
+//  KERNEL SALOME_Event : Define event posting mechanism
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  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. 
+// 
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SALOME_Event.hxx
+//  Author : Sergey ANIKIN
+//  Module : KERNEL
+//  $Header$
 
 
 #ifndef SALOME_Event_HeaderFile
 #define SALOME_Event_HeaderFile
 
 #include <qevent.h>
-#include <qsemaphore.h>
 
-class SALOME_Semaphore : public QSemaphore
-{
-public:
-  SALOME_Semaphore() : QSemaphore( 1 ) {}
-  virtual ~SALOME_Semaphore();
-};
+#define SALOME_EVENT QEvent::Type( QEvent::User + 10000 )
+
+class QSemaphore;
 
-class SALOME_Event : public QCustomEvent
+//===========================================================
+/*!
+ *  Class: SALOME_Event
+ *  Description: 
+ *  This class encapsulates data and functionality required for 
+ *  posting component-specific events. These events are then dispatched
+ *  by QAD_Desktop to corresponding component GUI object, on the basis of 
+ *  <type> value passed to the constructor. SALOME_Event objects can be used 
+ *  by any thread belonging to the GUI process.
+ *
+ *  It is possible to make the thread that creates SALOME_Event
+ *  wait until the event is processed by the component GUI, SALOME_Event
+ *  should be constructed with <wait> == TRUE in such a case.
+ *
+ *  SALOME_Event objects should be created on the heap. QAD_Desktop deletes
+ *  these objects as soon as they have been processed.
+ *
+ *  Usage:
+ *  - create SALOME_Event object on the heap with proper <type> and <wait> parameters. 
+ *    Components can derive their own event class from SALOME_Event
+ *    in order to pass custom data to the event handler.
+ *  - call process() method to post the event.
+ * 
+ *  processed() method is used by the desktop to signal that event processing 
+ *  has been completed.
+ *  
+ *  NOTE: 
+ *  1. Never create SALOME_Event with <wait> == TRUE in code that is 
+ *     supposed to be called from built-in GUI Python console, for this will result
+ *     in GUI process deadlock.
+ *  2. Never use pointers to the event after it has been processed to avoid
+ *     application crashes!
+ */
+//===========================================================
+
+class SALOME_Event
 {
 public:
-  SALOME_Event( int salomeEventType, SALOME_Semaphore* s = 0 );
+  SALOME_Event( int salomeEventType, bool wait );
+  virtual ~SALOME_Event();
 
   int getType() const { return myType; }
+
+  void process();
   void processed();
-  
-private:
-  SALOME_Semaphore* getSemaphore() { return (SALOME_Semaphore*)data(); }
 
 private:
-  int myType;
+  int         myType;
+  bool        myWait;
+  QSemaphore* mySemaphore;
 };
 
 #endif
index 3538e40a30136b79e61c9cb2a622b9321ad3a6d9..ab72ecc6f88808b7c9e9c65cdc009d9155c286eb 100644 (file)
 #endif
 
 // Open CASCADE Includes
+#include <OSD_SharedLibrary.hxx>
 #include <OSD_LoadMode.hxx>
 #include <OSD_Function.hxx>
 #include <TCollection_AsciiString.hxx>
@@ -448,20 +449,38 @@ bool QAD_Desktop::eventFilter( QObject* o, QEvent* e )
       }
     }
   }
-  else if ( e->type() == QEvent::User + 1 ) { // SALOME_Event has type QEvent::User + 1
-    SALOME_Event* aSE = (SALOME_Event*)e;
-    MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 1 : o = " << o << ", e = " << e);
-    // here we do the job...
-    sleep( 5 );
+  else if ( e->type() == SALOME_EVENT ) { 
+    SALOME_Event* aSE = (SALOME_Event*)((QCustomEvent*)e)->data();
+    MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 1 : o = " << o << ", e = " << aSE);
 
+    processEvent( aSE );
     MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 2" );
+
+    // Signal the calling thread that the event has been processed
     aSE->processed();
     MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 3" );
+
+    ((QCustomEvent*)e)->setData( 0 );
+    delete aSE;
     return TRUE;
   }
   return QMainWindow::eventFilter( o, e );
 }
 
+/*!
+    Dispatches <theEvent> to the target component GUI
+*/
+void QAD_Desktop::processEvent( SALOME_Event* theEvent )
+{
+  if ( !theEvent )
+    return;
+
+  for ( ComponentMap::iterator it = myComponents.begin(); it != myComponents.end(); it++ ) {
+    if ( it.data()->CanProcessEvent( theEvent ) && it.data()->ProcessEvent( theEvent ) )
+      break;
+  }
+}
+
 /*!
     Creates and initializes the standard file operations
     such as 'New/Open/Save/SaveAs/Close' and 'Help'.
index 7cce46ea3bdf39613d9d64a9dc86039dc5cb1d6b..94a4a3fe19ab5abfa642c7bafc4c8e36fec650b0 100644 (file)
 #include <qfiledialog.h>
 #include <qtoolbutton.h>
 
-// Open CASCADE Includes
-#include <OSD_SharedLibrary.hxx>
-
 class QAD_XmlHandler;
 class SALOMEGUI;
+class SALOME_Event;
 
 class QAD_EXPORT QAD_Desktop : public QMainWindow
 {
@@ -319,6 +317,9 @@ protected:
 
     QMap<QString,QString> mapComponentName;
 
+private:
+    void processEvent( SALOME_Event* );
+
 private:
     typedef QMap<QString, SALOMEGUI*> ComponentMap;
 
index 9bf5578765af2b32f4e7ec86324b8b6ac8ccfab2..015d16722543ed1e230c323c689734f92fe2ad8e 100644 (file)
@@ -135,6 +135,13 @@ const char* SALOMEGUI_Swig::getComponentUserName( const char* ComponentName )
 {
   return QAD_Application::getDesktop()->getComponentUserName( ComponentName );
 }
+/*!
+  Loads component GUI library if not yet loaded
+*/
+void SALOMEGUI_Swig::loadComponentGUI( const char* ComponentName )
+{
+  QAD_Application::getDesktop()->getComponentGUI( QAD_Application::getDesktop()->getComponentUserName( ComponentName ) );
+}
 
 /*!
   Returns the number of selected objects.
index 0af5330a197e01a326078d4902d740e071661aa3..8718063fefd991cf3ef14a12c487bc2f500fe25a 100644 (file)
@@ -72,6 +72,7 @@ public:
 /* component name */
   const char* getComponentName( const char* ComponentUserName );
   const char* getComponentUserName( const char* ComponentName );
+  void loadComponentGUI( const char* ComponentName );
 
 protected:
   int _studyId;
index d5c5a5007d75ea05a0da6c33922f9807ebc34a3a..f0237824e92511006875847a84c57363845ade97 100644 (file)
@@ -82,4 +82,6 @@ class SALOMEGUI_Swig
 /* component name */
   const char* getComponentName( const char* ComponentUserName );
   const char* getComponentUserName( const char* ComponentName );
+
+  void loadComponentGUI( const char* ComponentName );
 };