From: mkr Date: Mon, 24 Oct 2005 09:08:42 +0000 (+0000) Subject: Patch from Christian CAREMOLI for bug PAL10339 : random GUI freeze. X-Git-Tag: V2_2_6~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9320c5c85bf20de820ee87ae04c1a8ecb49666e0;p=modules%2Fsuperv.git Patch from Christian CAREMOLI for bug PAL10339 : random GUI freeze. --- diff --git a/src/SUPERVGUI/SUPERVGUI_Main.cxx b/src/SUPERVGUI/SUPERVGUI_Main.cxx index a542e7a..a4c433b 100644 --- a/src/SUPERVGUI/SUPERVGUI_Main.cxx +++ b/src/SUPERVGUI/SUPERVGUI_Main.cxx @@ -1284,71 +1284,105 @@ void SUPERVGUI_Thread::KillThread( bool theValue ) myMutex.unlock(); } -typedef TVoidMemFun2ArgEvent TNodeSyncEvent; - -void SUPERVGUI_Thread::run() -{ - myMain->startTimer(); - - // GUI cycle to handle events coming for Engine - while ( myIsActive ) { - - SUPERV_CNode aNode = NULL; - SUPERV::GraphEvent aEvent = SUPERV::UndefinedEvent ; - SUPERV::GraphState aState = SUPERV::UndefinedState ; +template +class TVoidMemFun3ArgEvent: public SALOME_Event{ +public: + typedef void (TObject::* TAction)(TArg,TArg1,TArg2); + TVoidMemFun3ArgEvent(TObject* theObject, TAction theAction, TArg theArg, TArg1 theArg1, TArg2 theArg2): + myObject(theObject), + myAction(theAction), + myArg(theArg), + myArg1(theArg1), + myArg2(theArg2) + {} + virtual void Execute(){ + (myObject->*myAction)(myArg,myArg1,myArg2); + } +private: + TObject* myObject; + TAction myAction; + TStoreArg myArg; + TStoreArg1 myArg1; + TStoreArg2 myArg2; +}; - // blocking function of Engine. Return from there only after anEvent happens on node aNode - myMain->getDataflow()->Event(aNode, aEvent, aState); +typedef TVoidMemFun3ArgEvent TMainRunEvent; +/** + * main_thread_run must be executed in the qt main thread + * It is activated by calling ProcessVoidEvent + */ +void SUPERVGUI_Thread::main_thread_run(SUPERV_CNode& aNode, SUPERV::GraphEvent& aEvent, SUPERV::GraphState& aState) +{ // in case node "said" something during changing state through notification mechanism - output it - qApp->lock(); // mkr : IPAL9564 myMain->syncNotification(); - qApp->unlock(); // "kill" or undefined event came if (( aEvent == SUPERV::UndefinedEvent && aState == SUPERV::UndefinedState ) || - ( aEvent == SUPERV::NoEvent && aState == SUPERV::NoState ) || - ( aEvent == SUPERV::KillEvent && aState == SUPERV::KillState )) { + ( aEvent == SUPERV::NoEvent && aState == SUPERV::NoState ) || + ( aEvent == SUPERV::KillEvent && aState == SUPERV::KillState )) { myIsActive = false; } else { // a "normal" execution event came char* aName = NULL; if ( aNode != NULL && !CORBA::is_nil( aNode ) ) - aName = aNode->Name(); + aName = aNode->Name(); + // What follow is not quite sure. The entire function is posted to the main qt thread. + // So all executions are serialized. Is it really possible to call execute when another + // execute is running. I don't think so (C Caremoli) // this function is asynchronious. The call does NOT wait when SUPERVGUI_Main::execute finishes // handling the event. So: SUPERVGUI_Main::execute must be fast, in order we don't get here again // on the next loop iteration, BEFORE previous SUPERVGUI_Main::execute finished. - ProcessVoidEvent( new TNodeSyncEvent( myMain, &SUPERVGUI_Main::execute, aName, aState ) ); + myMain->execute(aName, aState ); } - + // execution is finished. just set a "finished" message(s) if ( !myIsActive ) { switch ( myMain->getDataflow()->State() ) { case SUPERV_Editing : - myMain->getMessage()->setMessage( myMain->getDataflow()->IsReadOnly()? - tr("MSG_GRAPH_READONLY"): tr("MSG_GRAPH_EDITING") ); - break; + myMain->getMessage()->setMessage( myMain->getDataflow()->IsReadOnly()? + tr("MSG_GRAPH_READONLY"): tr("MSG_GRAPH_EDITING") ); + break; case SUPERV_Suspend : - myMain->getMessage()->setMessage( tr("MSG_GRAPH_SUSPENDED") ); - break; + myMain->getMessage()->setMessage( tr("MSG_GRAPH_SUSPENDED") ); + break; case SUPERV_Done : - myMain->getMessage()->setMessage( tr("MSG_GRAPH_FINISHED") ); - break; + myMain->getMessage()->setMessage( tr("MSG_GRAPH_FINISHED") ); + break; case SUPERV_Error : - myMain->getMessage()->setMessage( tr("MSG_GRAPH_ABORTED") ); - break; + myMain->getMessage()->setMessage( tr("MSG_GRAPH_ABORTED") ); + break; case SUPERV_Kill: - myMain->getMessage()->setMessage( tr("MSG_GRAPH_KILLED") ); - break; + myMain->getMessage()->setMessage( tr("MSG_GRAPH_KILLED") ); + break; } // end of switch // asv 03.02.05 : fix for PAL6859, not very good, but works.. myMain->sync(); } // end of if !myIsActive - } // end of while( myIsActive ) +} +void SUPERVGUI_Thread::run() +{ + myMain->startTimer(); + + // GUI cycle to handle events coming for Engine + while ( myIsActive ) { + + SUPERV_CNode aNode = NULL; + SUPERV::GraphEvent aEvent = SUPERV::UndefinedEvent ; + SUPERV::GraphState aState = SUPERV::UndefinedState ; + + // blocking function of Engine. Return from there only after anEvent happens on node aNode + myMain->getDataflow()->Event(aNode, aEvent, aState); + + ProcessVoidEvent( new TMainRunEvent( this, &SUPERVGUI_Thread::main_thread_run,aNode, aEvent, aState ) ); + + } // end of while( myIsActive ) + QThread::exit(); } diff --git a/src/SUPERVGUI/SUPERVGUI_Main.h b/src/SUPERVGUI/SUPERVGUI_Main.h index 274a179..7b096bc 100644 --- a/src/SUPERVGUI/SUPERVGUI_Main.h +++ b/src/SUPERVGUI/SUPERVGUI_Main.h @@ -223,6 +223,7 @@ class SUPERVGUI_Thread : public QObject, public QThread { protected: void run(); + void main_thread_run(SUPERV_CNode& aNode, SUPERV::GraphEvent& aEvent, SUPERV::GraphState& aState); private: bool myIsActive;