]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkBlackBox.cxx
bbtk now depends on crea !
[bbtk.git] / kernel / src / bbtkBlackBox.cxx
index b7a7ec78f4ee6d3d71be5de580d38085f24954c3..a4dea22c8624d2e0959d574c573799a54122dd72 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBox.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/12/08 12:53:45 $
-  Version:   $Revision: 1.32 $
+  Date:      $Date: 2008/12/11 15:30:04 $
+  Version:   $Revision: 1.38 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -153,42 +153,6 @@ namespace bbtk
   //=========================================================================
 
 
-  //=========================================================================
-  /// Main processing method of the box.
-  void BlackBox::bbExecute(bool force)
-  {
-    bbtkDebugMessageInc("process",2,
-                       "=> BlackBox::bbExecute("<<(int)force<<") ["
-                       <<bbGetFullName()<<"]"<<std::endl);
-    // If already executing : return
-    if (bbGetExecuting()) 
-      {
-       bbtkDebugMessage("process",2,
-                        " -> already executing : bailing out"<<std::endl);
-       return;
-      }
-
-    // If execution frozen : return
-    if (bbGlobalGetFreezeExecution()) 
-      {
-       bbtkDebugMessage("process",2,
-                        " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
-      }
-
-    BBTK_BUSY_CURSOR;
-
-    // If force is true then update is triggered even if the box is UPTODATE
-    //    if (force) bbSetModifiedStatus();
-
-    // Calls the main recursive update method 
-    bbBackwardUpdate(Connection::Pointer());
-
-    bbtkDebugMessageDec("process",2,
-                       "<= BlackBox::bbExecute() ["
-                       <<bbGetFullName()<<"]"<<std::endl);
-  }
-  //=========================================================================
 
   //=========================================================================
   std::string BlackBox::bbGetFullName() const
@@ -382,7 +346,7 @@ namespace bbtk
   bool BlackBox::bbCanReact() const 
   { 
     return ( bbGlobalGetSomeBoxExecuting() 
-#ifdef _USE_WXWIDGETS_
+#ifdef USE_WXWIDGETS
             || Wx::IsSomeWindowAlive() 
 #endif
             ); 
@@ -444,16 +408,18 @@ namespace bbtk
 
 
   //=========================================================================
-  void BlackBox::AddChangeObserver(const std::string& output_name
+  void BlackBox::bbAddOutputObserver(const std::string& output
                                   OutputChangeCallbackType f)
   {
+    bbGetOutputConnector(output).AddChangeObserver(f);
   }  
   //=========================================================================
 
   //=========================================================================
-  void BlackBox::RemoveChangeObserver(const std::string& output_name, 
+  void BlackBox::bbRemoveOutputObserver(const std::string& output_name, 
                                      OutputChangeCallbackType f)
   {
+    bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
   }
   //=========================================================================
 
@@ -572,13 +538,17 @@ namespace bbtk
   void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
                                         IOStatus s)
   {
+    bbtkDebugMessageInc("change",5,
+                       "=> BlackBox::bbSetStatusAndPropagate(input,"
+                       <<GetIOStatusString(s)<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
     if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
     c->SetStatus(s);
     OutputConnectorMapType::const_iterator o;  
     for ( o = bbGetOutputConnectorMap().begin(); 
          o != bbGetOutputConnectorMap().end(); ++o )                   
       {                                                                        
-       //      bbSetStatusAndPropagate(o->second, OUTOFDATE);
        if (o->second->GetStatus()==UPTODATE) 
          {
            o->second->SetStatus(OUTOFDATE);
@@ -590,93 +560,21 @@ namespace bbtk
           (c==bbGetInputConnectorMap().find("BoxExecute")->second))
         && (bbCanReact() ) )
       {
-       bbtkDebugMessage("modified",2,
+       bbtkDebugMessage("change",2,
                         "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
         bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
       }    
+    bbtkDebugMessageInc("change",5,
+                       "<= BlackBox::bbSetStatusAndPropagate(input) ["
+                       <<bbGetFullName()<<"]"<<std::endl);
   }
   //=========================================================================
 
-  //=========================================================================
-  void BlackBox::bbSetStatusAndPropagate(BlackBoxOutputConnector* c,
-                                        IOStatus s)
-  {
-    bbtkError("bbSetStatusAndPropagate(BlackBoxOutputConnector* c,IOStatus s)");
-    /*
-    if (i->GetStatus()==UPTODATE) 
-      {
-       i->second->SetStatus(s);
-       i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
-      }
-    */
-  }
-  //=========================================================================
-
- ///  Signals that the BlackBox has been modified
-  /*
-  void BlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
-  {
-    bbtkDebugMessage("modified",1,
-                    "==> BlackBox::bbSetModifiedStatus("<<c<<") ["
-                    <<bbGetFullName()<<"]"<<std::endl);
-    
-    if ( (c==bbGetInputConnectorMap().find("WinHide")->second) )
-      //        && (bbCanReact()))
-      {
-       bbtkDebugMessage("modified",2,
-                        "-> Hide triggered by WinHide input change"
-                        <<std::endl);
-       this->bbHideWindow();
-       this->bbSetStatus(MODIFIED); 
-       return;
-      }
-    if ( (c==bbGetInputConnectorMap().find("WinClose")->second) )
-      //        && (bbCanReact()))
-      {
-       bbtkDebugMessage("modified",2,
-                        "-> Close triggered by WinClose input change"
-                        <<std::endl);
-       this->bbHideWindow();
-       this->bbSetStatus(MODIFIED); 
-       return;
-      }
-    
-    if ( ( bbBoxProcessModeIsReactive()  ||
-          (c==bbGetInputConnectorMap().find("BoxExecute")->second))
-        && (bbCanReact() ) )
-      {
-       bbtkDebugMessage("modified",2,
-                        "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
-       this->bbSetStatus(MODIFIED); 
-        bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
-      }
-    
-    //else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
-     // { 
-//     bbtkDebugMessage("modified",2,"-> Already modified"<<std::endl);
-//     return;
- //     }
-   
-    else 
-      {
-       bbtkDebugMessage("modified",2,"-> Status set to modified"<<std::endl);
-       this->bbSetStatus(MODIFIED); 
-      }
-    this->bbSignalOutputModification(false);
-
-  bbtkDebugMessageDec("process",5,
-                       "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
-                       <<bbGetFullName()<<"]"<<std::endl);
-  }  
-*/
-  //=========================================================================
 
   //=========================================================================  
   void BlackBox::bbSignalOutputModification(bool reaction)
   {
-    bbtkDebugMessageInc("process",5,
+    bbtkDebugMessageInc("change",5,
                        "=> BlackBox::bbSignalOutputModification("
                        <<reaction<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
@@ -685,16 +583,20 @@ namespace bbtk
     for ( i  = bbGetOutputConnectorMap().begin(); 
          i != bbGetOutputConnectorMap().end(); ++i) 
       {
-       if (i->second->GetStatus()==UPTODATE) 
-         {
-           //      i->second->SetStatus(MODIFIED);
+       //      std::cout << "Stat = "
+       //<<GetIOStatusString(i->second->GetStatus())
+       //                <<std::endl;
+       // LG : CANNOT SIGNAL ONLY WHEN UPTODATE 
+       // See bbtkSampleOutputObserver
+       //      if (i->second->GetStatus()==UPTODATE) 
+       //        {
            i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
-         }
+           //    }
       } 
 
     if (reaction) bbGlobalProcessExecutionList();
 
-    bbtkDebugMessageDec("process",5,
+    bbtkDebugMessageDec("change",5,
                        "<= BlackBox::bbSignalOutputModification() ["
                        <<bbGetFullName()<<"]"<<std::endl);
     
@@ -704,7 +606,7 @@ namespace bbtk
   void BlackBox::bbSignalOutputModification(const std::string& output,
                                            bool reaction)
   {
-    bbtkDebugMessageInc("process",5,
+    bbtkDebugMessageInc("change",5,
                        "=> BlackBox::bbSignalOutputModification("
                        <<output<<","<<reaction<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
@@ -718,9 +620,8 @@ namespace bbtk
          bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
        }
 
-    if (i->second->GetStatus()==UPTODATE) 
-      {
-       //      i->second->SetStatus(MODIFIED);
+    //    if (i->second->GetStatus()==UPTODATE) 
+    //      {
        i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
        // Has to notify the output "BoxChange" also
        if (output != "BoxChange") 
@@ -728,14 +629,13 @@ namespace bbtk
            i = bbGetOutputConnectorMap().find("BoxChange");
            if ( i != bbGetOutputConnectorMap().end() ) 
              {
-               //              i->second->SetStatus(MODIFIED);
                i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
              }
          }
        if (reaction) bbGlobalProcessExecutionList();
-      }
+       //      }
 
-    bbtkDebugMessageDec("process",5,
+    bbtkDebugMessageDec("change",5,
                        "<= BlackBox::bbSignalOutputModification("
                        <<output<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
@@ -746,7 +646,7 @@ namespace bbtk
   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
        bool reaction)
   {
-    bbtkDebugMessageInc("process",5,
+    bbtkDebugMessageInc("change",5,
                        "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
                        <<bbGetFullName()<<"]"<<std::endl);
     OutputConnectorMapType::iterator i;
@@ -762,37 +662,153 @@ namespace bbtk
          {
            bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
          }
-       // Already OUTOFDATE : noting to do
-       if (i->second->GetStatus()==UPTODATE)
-         {
-           //  i->second->SetStatus(MODIFIED);
+
+       //      if (i->second->GetStatus()==UPTODATE)
+       //        {
            i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
            changed = true;
-         }
+           //  }
       }
     // Has to notify the output "BoxChange" also
     i = bbGetOutputConnectorMap().find("BoxChange");
     if ( changed && (i != bbGetOutputConnectorMap().end())) 
       {
-       // Already OUTOFDATE : noting to do
-       if (i->second->GetStatus()==UPTODATE) 
-         {
-           //  i->second->SetStatus(MODIFIED);
+       // if (i->second->GetStatus()==UPTODATE) 
+       //        {
            i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
            if (reaction) bbGlobalProcessExecutionList();
-         }
+           //  }
       }
 
-    bbtkDebugMessageDec("process",5,
+    bbtkDebugMessageDec("change",5,
                        "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
                        <<bbGetFullName()<<"]"<<std::endl);
 
   }  
   //=========================================================================   
 
+
+
+
+
+
+
+  //=========================================================================
+  /// Main processing method of the box.
+  void BlackBox::bbExecute(bool force)
+  {
+    bbtkDebugMessageInc("process",2,
+                       "=> BlackBox::bbExecute("<<(int)force<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    // If already executing : return
+    /*
+    if (bbGetExecuting()) 
+      {
+       bbtkDebugMessage("process",2,
+                        " -> already executing : abort"<<std::endl);
+       return;
+      }
+    */
+
+    // If execution frozen : return
+    if (bbGlobalGetFreezeExecution()) 
+      {
+       bbtkDebugMessage("process",2,
+                        " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
+      }
+
+    BBTK_BUSY_CURSOR;
+
+    // If force is true then update is triggered even if the box is UPTODATE
+    //    if (force) bbSetModifiedStatus();
+
+    // Calls the main recursive execution method 
+    bbRecursiveExecute(Connection::Pointer());
+
+    bbtkDebugMessageDec("process",2,
+                       "<= BlackBox::bbExecute() ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+  }
+  //=========================================================================
+
+
+  //=========================================================================
+  /// Main recursive processing method of the box.
+  void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
+  {
+    bbtkDebugMessageInc("process",3,
+                       "=> BlackBox::bbRecursiveExecute("
+                       <<(caller?caller->GetFullName():"0")<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+
+    // If already executing : return
+    if (bbGetExecuting()) 
+      {
+       bbtkDebugMessage("process",3,
+                        " -> already executing : abort"<<std::endl);
+       return; 
+      }
+
+    bbSetExecuting(true);
+    bool wasExecuting = bbGlobalGetSomeBoxExecuting();
+    bbGlobalSetSomeBoxExecuting(true);
+
+    // Updates its inputs
+    IOStatus s = bbUpdateInputs();
+    
+    if ( (s != UPTODATE) ||
+        bbBoxProcessModeIsAlways() )
+      {
+       // Displays the window (WxBlackbox)
+       //      bbShowWindow(caller);
+
+       // Actual processing (virtual)
+       this->bbProcess();
+       
+       
+       // Update the I/O statuses
+       bbComputePostProcessStatus();
+      }
+    else 
+      {
+       // Test output status...
+       OutputConnectorMapType::iterator o;
+       for ( o = bbGetOutputConnectorMap().begin(); 
+             o!= bbGetOutputConnectorMap().end(); ++o) 
+         {
+           if (o->second->GetStatus() != UPTODATE)
+             {
+               bbtkWarning("BlackBox::bbRecursiveExecute ["
+                           <<bbGetFullName()
+                           <<"] : all inputs are Up-to-date but output '"
+                           <<o->first<<"' is Out-of-date ???");
+             }
+         }
+       
+        bbtkDebugMessage("process",3," -> Up-to-date : nothing to do"
+                        <<std::endl);
+      }
+
+    bbtkDebugMessage("process",3,
+            "<= BlackBox::bbRecursiveExecute() ["
+            <<bbGetFullName()<<"]"<<std::endl);
+
+    bbSetExecuting(false);
+    bbGlobalSetSomeBoxExecuting(wasExecuting);
+
+    return; 
+
+  }
+  //=========================================================================
+  
+   
+
+
+
   //=========================================================================
   /// Updates the BlackBox inputs
-  /// Calls BackwardUpdate on all BlackBoxInputConnector
+  /// Calls RecursiveExecute on all BlackBoxInputConnector
   /// \returns The maximum of final IOStatus after each input update
   IOStatus BlackBox::bbUpdateInputs()
   {
@@ -812,9 +828,21 @@ namespace bbtk
        //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
        //      == typeid(Void) ) 
        //  continue;
-       i->second->BackwardUpdate();
+       bbtkDebugMessageDec("change",2,
+                           bbGetName()<<"."<<i->first
+                           <<" ["<<i->second<<"] "
+                           <<" status before update = '"
+                           <<GetIOStatusString(i->second->GetStatus())
+                           <<"'"<<std::endl);
+       i->second->RecursiveExecute();
        IOStatus t = i->second->GetStatus();
        if (t > s) s = t;
+       bbtkDebugMessageDec("change",2,
+                           bbGetName()<<"."<<i->first
+                           <<" ["<<i->second<<"] "
+                           <<" status before process = '"
+                           <<GetIOStatusString(i->second->GetStatus())
+                           <<"'"<<std::endl);
       }
     
     bbtkDebugMessageDec("process",4,
@@ -831,6 +859,11 @@ namespace bbtk
   /// Computes the final IOStatus of inputs and outputs after processing
   void BlackBox::bbComputePostProcessStatus()
   {
+    bbtkDebugMessageInc("process",4,
+                       "=> BlackBox::bbComputePostProcessStatus() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);   
+
     IOStatus new_output_status = UPTODATE;
     if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
 
@@ -843,8 +876,16 @@ namespace bbtk
        if (t == OUTOFDATE) new_output_status = OUTOFDATE;
        // A previously MODIFIED status turns to UPTODATE
        if (t==MODIFIED) i->second->SetStatus(UPTODATE);
+       bbtkDebugMessage("change",2,
+                        bbGetName()<<"."<<i->first<<" : "
+                        << GetIOStatusString(t) << " -> "
+                        << GetIOStatusString(i->second->GetStatus())
+                        << std::endl);
       }
-
+       bbtkDebugMessage("change",2,
+                        bbGetName()<<" new output status : "
+                        << GetIOStatusString(new_output_status)
+                        <<std::endl);
     // Update the output statuses
     OutputConnectorMapType::iterator o;
     for ( o = bbGetOutputConnectorMap().begin(); 
@@ -852,6 +893,12 @@ namespace bbtk
       {
        o->second->SetStatus(new_output_status);
       }
+
+    bbtkDebugMessageInc("process",4,
+                       "<= BlackBox::bbComputePostProcessStatus() ["
+                       <<bbGetFullName()<<"]"
+                       <<std::endl);   
+
   }
   //==================================================================
 
@@ -872,13 +919,8 @@ namespace bbtk
        bbtkError("no input called '"<<name<<"'");
       }
     i->second->SetConnection(c);
-
-    // Check the status of the from.output of c 
-    // to set the new status of the input
-    IOStatus s = MODIFIED;
-    if ( c->GetBlackBoxFrom()->bbGetOutputConnector(c->GetBlackBoxFromOutput()).GetStatus() == OUTOFDATE ) 
-      s = OUTOFDATE;
-    bbSetStatusAndPropagate(i->second,s);
+    // The input *MUST* be set OUTOFDATE to update its input on next execution
+    bbSetStatusAndPropagate(i->second,OUTOFDATE);
     
     bbtkDebugMessage("connection",2,
                        "<== BlackBox::bbConnectInput(\""