]> Creatis software - bbtk.git/commitdiff
* Major changes on IOStatus update / propagation
authorguigues <guigues>
Mon, 8 Dec 2008 12:53:30 +0000 (12:53 +0000)
committerguigues <guigues>
Mon, 8 Dec 2008 12:53:30 +0000 (12:53 +0000)
* Output modifications are now caught through an observer mechanism (using boost signal/slot)

20 files changed:
kernel/doc/bbtkDevelopersGuide/bbtkDevelopersGuide.tex
kernel/src/bbtkAtomicBlackBox.cxx
kernel/src/bbtkAtomicBlackBox.h
kernel/src/bbtkBlackBox.cxx
kernel/src/bbtkBlackBox.h
kernel/src/bbtkBlackBoxInputConnector.cxx
kernel/src/bbtkBlackBoxInputConnector.h
kernel/src/bbtkBlackBoxOutputConnector.cxx
kernel/src/bbtkBlackBoxOutputConnector.h
kernel/src/bbtkComplexBlackBox.cxx
kernel/src/bbtkComplexBlackBox.h
kernel/src/bbtkConnection.cxx
kernel/src/bbtkConnection.h
kernel/src/bbtkKWBlackBox.cxx
kernel/src/bbtkKWBlackBox.h
kernel/src/bbtkMessageManager.cxx
kernel/src/bbtkWxBlackBox.cxx
kernel/src/bbtkWxBlackBox.h
packages/wxvtk/src/bbwxvtkViewer2D.cxx
packages/wxvtk/src/bbwxvtkViewer2D.h

index f48f68f0535a1a00bf56d60ec135a4c83d7dcdef..7d19f1223a48c6a60aa1feb5204a61bcba0c7865 100644 (file)
-\documentclass[a4paper,11pt]{report}
+\documentclass[a4paper,11pt,final]{article}
 \input{config.tex}
 
 
 
 \begin{document}
+\bbtkGuide[Developer's Guide]
 
-\begin{center}
 
-{\Large \BBTK}
-\vspace{1cm}
 
-{\Huge Developers' Guide}
-\vspace{1cm}
 
-\bbtk version \bbtkVersion
-\vspace{0.5cm}
 
+% ==========================================
+\tableofcontents
+% ==========================================
 
-Last modified on : September 16, 2008 \\
-Generated on : \today 
-\vspace{0.5cm}
-\end{center}
-\begin{center}
-Eduardo Davila, Laurent Guigues, Jean-Pierre Roux 
-\end{center}
-\begin{center}
-CREATIS-LRMN, Centre de Recherche en Imagerie Medicale \\ CNRS UMR 5220, INSERM U620\\
-INSA Lyon\\
-Universit\'e Claude-Bernard Lyon 1
-\end{center}
-
+% ==========================================
+\newpage
+\hrule
 
+% ==========================================
+\section{Introduction}
+% ==========================================
 
 % ==========================================
-\tableofcontents
+\section{Pipeline processing algorithm}
 % ==========================================
 
-\chapter{Introduction}
+Each input of a black box instance has a Status, 
+of type IOStatus (defined in bbtkConnection.h) 
+which can take one of the three values:
+\begin{itemize}
+\item UPTODATE (==0): The input did not change since last processing 
+\item MODIFIED (==1): [Initial value on construction] The input changed since last processing but is up-to-date with the amont box to which it is connected, if any.
+\item OUTOFDATE (==2): The input changed since last processing and is out-of-date with the amont box to which it is connected.
+\end{itemize}
+The status of an input is stored by the class BlackBoxInputConnector.
+
+Each output of a black box instance also has a Status, 
+of type IOStatus but which can only take the two values:
+\begin{itemize}
+\item UPTODATE (==0): The output is up-to-date (the box need not be reprocessed).
+\item OUTOFDATE (==2): [Initial value on construction] The output is out-of-date (the box need to be reprocessed).
+\end{itemize}
+The status of an output is stored by the class BlackBoxOutputConnector.
+
+
+The main execution method of a black box is bbExecute.
+bbExecute checks werther the box is not already executing (bbGetExecuting()) 
+to prevent reentrance and 
+checks werther the execution is not frozen (bbGlobalGetFreezeExecution()).
+If it is not the case then it calls bbBackwardUpdate which is 
+the main recursive pipeline processing method of a box, giving it a 
+NULL Connection::Pointer.
+
+bbBackwardUpdate is defined in AtomicBlackBox:
+
+\bigskip\hrule\begin{verbatim}
+void AtomicBlackBox::bbBackwardUpdate ( Connection::Pointer caller )
+{
+  // Updates the box inputs. Returns the max input IOStatus after update
+  IOStatus s = bbUpdateInputs();
+  // If at least one input is modified or BoxProcessMode=='Always'
+  if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
+    {
+      // User process
+      bbProcess();
+      // Displays the window (overloaded in widget Blackboxes, WxBlackBox, KWBlackBox, etc.)
+      bbShowWindow(caller);
+      // Compute the final status of inputs and outputs
+      bbComputePostProcessStatus();
+    }
+}
+\end{verbatim}\hrule\bigskip
+
+bbUpdateInputs iterates over the InputConnector of the box and 
+calls BackwardUpdate on each one. It returns the max of the final 
+status of the input connectors:
+\bigskip\hrule\begin{verbatim}
+IOStatus BlackBox::bbUpdateInputs()
+{
+  IOStatus s = UPTODATE;
+  InputConnectorMapType::iterator i;
+  for ( i = bbGetInputConnectorMap().begin(); 
+        i!= bbGetInputConnectorMap().end(); ++i) 
+    {
+      i->second->BackwardUpdate();
+      IOStatus t = i->second->GetStatus();
+      if (t > s) s = t;
+    }
+  return s;    
+}
+\end{verbatim}\hrule\bigskip
+
+\bigskip\hrule\begin{verbatim}
+void BlackBoxInputConnector::BackwardUpdate()
+{
+  // If connected and OUTOFDATE : recursive update
+  // Post-update status is updated by the connection 
+  // (either MODIFIED or OUTOFDATE)
+   if ( mConnection && (mStatus == OUTOFDATE) ) 
+    {
+      mConnection->BackwardUpdate();
+    }
+}
+\end{verbatim}\hrule\bigskip
+
+\bigskip\hrule\begin{verbatim}
+void Connection::BackwardUpdate()
+{
+  // Calls bbBackwardUpdate on the initial box
+  mFrom->bbBackwardUpdate(GetThisPointer<Connection>());
+  // Transfers the data from the initial box output to the 
+  // final box input adapting it if necessary
+  TransferData();
+  // Updates the status of the final box input
+  IOStatus s = MODIFIED;
+  if ( mFrom->bbGetOutputConnector(mOutput).GetStatus() == OUTOFDATE) 
+    s = OUTOFDATE,
+  mTo->bbGetInputConnector(mInput).SetStatus(s);
+}
+\end{verbatim}\hrule\bigskip
+
 
 
-\chapter{Misc}
+% ==========================================
+\section{Misc}
+% ==========================================
 
-\section{Displaying messages}
+\subsection{Displaying messages}
 
 \begin{verbatim}
 bbtkMessage("Kind",level,"message "<<"to "<<" display : i="<<i<<std::endl);
index 3ee7d62b05d0e98e685e87f7683b04fcbc9c382a..d42185163bdf9dd230273a65edeadd0bb414e272 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkAtomicBlackBox.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/11/25 11:17:13 $
-  Version:   $Revision: 1.10 $
+  Date:      $Date: 2008/12/08 12:53:35 $
+  Version:   $Revision: 1.11 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -86,7 +86,7 @@ namespace bbtk
 
   //=========================================================================
   /// Main processing method of the box.
-  IOStatus AtomicBlackBox::bbBackwardUpdate( Connection::Pointer caller )
+  void AtomicBlackBox::bbBackwardUpdate( Connection::Pointer caller )
   {
     bbtkDebugMessageInc("process",3,
                        "=> AtomicBlackBox::bbBackwardUpdate("
@@ -97,64 +97,35 @@ namespace bbtk
     if (bbGetExecuting()) 
       {
        bbtkDebugMessage("process",3,
-                        " -> already executing : bailing out"<<std::endl);
-       return bbGetStatus();
+                        " -> already executing : returning"<<std::endl);
+       return
       }
+
     bbSetExecuting(true);
     bool wasExecuting = bbGlobalGetSomeBoxExecuting();
     bbGlobalSetSomeBoxExecuting(true);
 
-    bbtkDebugMessage("process",5,"Initial Status  = "<<bbGetStatus()
-                    <<std::endl);
-    bbtkDebugMessage("process",5,"BoxProcessMode  = "
-                    <<bbGetInputBoxProcessMode()<<std::endl);
-   
-
-    if ( ( bbGetStatus() == MODIFIED ) ||
-        ( bbBoxProcessModeIsAlways() ) )
-      {
-
-       //      bbSetStatus(UPDATING);
-
-        // Updates its inputs
-        IOStatus s = bbUpdateInputs();
+    // Updates its inputs
+    IOStatus s = bbUpdateInputs();
     
-        bbtkDebugMessage("process",6,"=> AtomicBlackBox::bbBackwardUpdate("
-                       <<(caller?caller->GetFullName():"0")<<") ["
-                       <<bbGetFullName()<<"] : Inputs post-update status = "<<s<<std::endl);
-        // If all inputs are in UPTODATE post-update status 
-        // and mProcessMode is not "Always"
-        // then the box is now UPTODATE
-       IOStatus new_status;
-        if ( ( s == UPTODATE ) && 
-            ( ! bbBoxProcessModeIsAlways() ) ) 
-            {
-                new_status = UPTODATE;
-            }
-        else 
-            {
-                // else it remains MODIFIED
-                 new_status = MODIFIED;
-            }
-       bbSetStatus(new_status);
-
-        // User process
-        bbProcess();
-
-        // Displays the window (WxBlackbox)
-        bbShowWindow(caller);
-
-
+    if ( (s != UPTODATE) ||
+        bbBoxProcessModeIsAlways() )
+      {
+       // User process
+       bbProcess();
+       
+       // Displays the window (WxBlackbox)
+       bbShowWindow(caller);
+       
+       // Update the I/O statuses
+       bbComputePostProcessStatus();
       }
     else 
       {
-        bbtkDebugMessage("process",5,"Up-to-date : nothing to do"<<std::endl);
+        bbtkDebugMessage("process",5," -> Up-to-date : nothing to do"
+                        <<std::endl);
       }
 
-    bbtkDebugMessage("process",5,"=> AtomicBlackBox::bbBackwardUpdate("
-                    <<(caller?caller->GetFullName():"0")<<") ["
-                    <<bbGetFullName()<<"] : Final Status    = "
-                    <<bbGetStatus()<<std::endl);
     bbtkDebugMessage("process",3,
             "<= AtomicBlackBox::bbBackwardUpdate() ["
             <<bbGetFullName()<<"]"<<std::endl);
@@ -162,7 +133,7 @@ namespace bbtk
     bbSetExecuting(false);
     bbGlobalSetSomeBoxExecuting(wasExecuting);
 
-    return bbGetStatus();
+    return; // bbGetStatus();
 
   }
   //=========================================================================
@@ -222,10 +193,9 @@ namespace bbtk
   
   //=========================================================================
   ///  Sets the data of the input called <name>
-  void AtomicBlackBox::bbSetInput(
-                const std::string &name,
-                Data data, 
-                bool setModified )
+  void AtomicBlackBox::bbSetInput(const std::string &name,
+                                 Data data, 
+                                 bool setModified )
   {
     bbtkDebugMessageInc("data",7,
             "AtomicBlackBox::bbSetInput(\""<<name<<"\",data) ["
@@ -234,22 +204,21 @@ namespace bbtk
     ((AtomicBlackBoxInputDescriptor*)bbGetDescriptor()->GetInputDescriptor(name))->GetSetFunctor()->Set(this,data);
     
     if (setModified) 
-        {
-            bbSetModifiedStatus();
-        }
+      {
+       bbSetStatusAndPropagate(bbGetInputConnectorMap().find(name)->second,
+                               MODIFIED);
+      }
     
     bbtkDebugDecTab("data",7);
   }
   //=========================================================================
   
-    //=========================================================================
+  //=========================================================================
   ///  Sets the data of the input called <name>
-  void AtomicBlackBox::bbBruteForceSetInputPointer
-    (
-                    const std::string &name, 
-                    void* data, 
-                    bool setModified
-    )
+  void AtomicBlackBox::bbBruteForceSetInputPointer(const std::string &name, 
+                                                  void* data, 
+                                                  bool setModified
+                                                  )
   {
     bbtkDebugMessageInc("data",7,
             "AtomicBlackBox::bbBruteForceSetInputPointer(\""
@@ -262,7 +231,8 @@ namespace bbtk
     
     if (setModified) 
       {
-        bbSetModifiedStatus();
+       bbSetStatusAndPropagate(bbGetInputConnectorMap().find(name)->second,
+                               MODIFIED);
       }
     
     bbtkDebugDecTab("data",7);
index 34d85078ccb7528fabc8e1ece6fdb693be19e22f..9a00b95c555e4e2e6eab1b4662712eb961d22b52 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkAtomicBlackBox.h,v $
   Language:  C++
-  Date:      $Date: 2008/11/25 11:17:13 $
-  Version:   $Revision: 1.6 $
+  Date:      $Date: 2008/12/08 12:53:39 $
+  Version:   $Revision: 1.7 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -130,15 +130,11 @@ namespace bbtk
     //==================================================================   
     /// Recursive pipeline processing in backward direction 
     /// (recursion is in backward direction however execution always goes forward).
-    /// 
-    /// \returns The final status of the box (UPTODATE or MODIFIED)
-    ///
-    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
-    /// then : 
-    /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on upstream boxes)
-    /// - calls bbProcess which here simply calls the user callback bbUserProcess which does the actual processing. 
-    ///    bbProcess is overloaded in WxBlackBox to handle widget creation and show
-    virtual IOStatus bbBackwardUpdate(Connection::Pointer caller);
+    /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on amont boxes if needed)
+    /// - if the return value of bbUpdateInputs is not UPTODATE 
+    ///    - calls bbProcess
+    ///    - calls bbComputePostProcessStatus
+    virtual void bbBackwardUpdate(Connection::Pointer caller);
     //==================================================================
 
     //==================================================================
index f8ad055c388726fdc01ea57d9618ccbff060c30b..b7a7ec78f4ee6d3d71be5de580d38085f24954c3 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBox.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/12/03 13:35:22 $
-  Version:   $Revision: 1.31 $
+  Date:      $Date: 2008/12/08 12:53:45 $
+  Version:   $Revision: 1.32 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -36,6 +36,7 @@
 #include "bbtkPackage.h"
 #include "bbtkMessageManager.h"
 #include "bbtkFactory.h"
+#include "bbtkBlackBoxOutputConnector.h"
 
 #include "bbtkConfigurationFile.h"
 #include "bbtkWxBlackBox.h"
@@ -102,7 +103,7 @@ namespace bbtk
   //=========================================================================
   BlackBox::BlackBox(const std::string &name) 
     : 
-    bbmStatus(MODIFIED), 
+    //    bbmStatus(MODIFIED), 
     bbmExecuting(false),
     bbmName(name),
     bbmBoxProcessMode("Pipeline"),
@@ -123,7 +124,7 @@ namespace bbtk
   //=========================================================================
   BlackBox::BlackBox(BlackBox& from, const std::string &name) 
     :
-      bbmStatus(from.bbmStatus), 
+    //    bbmStatus(from.bbmStatus), 
       bbmExecuting(false),
       bbmName(name), 
       bbmBoxProcessMode(from.bbmBoxProcessMode),
@@ -178,7 +179,7 @@ namespace bbtk
     BBTK_BUSY_CURSOR;
 
     // If force is true then update is triggered even if the box is UPTODATE
-    if (force) bbSetModifiedStatus();
+    //    if (force) bbSetModifiedStatus();
 
     // Calls the main recursive update method 
     bbBackwardUpdate(Connection::Pointer());
@@ -439,8 +440,181 @@ namespace bbtk
   }
   //=========================================================================
 
+
+
+
+  //=========================================================================
+  void BlackBox::AddChangeObserver(const std::string& output_name, 
+                                  OutputChangeCallbackType f)
+  {
+  }  
+  //=========================================================================
+
+  //=========================================================================
+  void BlackBox::RemoveChangeObserver(const std::string& output_name, 
+                                     OutputChangeCallbackType f)
+  {
+  }
+  //=========================================================================
+
+
+  /*
+  //=========================================================================
+  ///  Sets the ChangeTime of input 
+  void BlackBox::bbSetInputChangeTime(BlackBoxInputConnector* c, 
+                                     const ChangeTime& t)
+  {
+    bbtkDebugMessage("change",1,
+                    "==> BlackBox::bbSetInputChangeTime("<<c<<","<<t<<") ["
+                    <<bbGetFullName()<<"]"<<std::endl);
+    
+    // If new time is greater than old one
+    if ( c->SetChangeTime(t) ) 
+      {
+       bool was_up_to_date = bbIsUpToDate();
+       // If new time is greater than the old max time of inputs
+       if ( mMaxInputChangeTime.Set(t) ) 
+         {
+           // If the box turned out-of-date
+           if ( was_up_to_date && bbIsOutOfDate() )
+             {
+               // 
+               if ( ( bbBoxProcessModeIsReactive()  ||
+                      (c==bbGetInputConnectorMap().find("BoxExecute")->second))
+                    && (bbCanReact() ) )
+                 {
+                   bbtkDebugMessage("change",2,
+                                    "an input of "
+                                    <<bbGetFullName()
+                                    <<" changed and box is in Reactive mode or BoxExecute input changed : adding it to the global execution list"
+                                    <<std::endl);
+                   bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
+                 }
+               // Have to propagate the modification to aval boxes
+               OutputConnectorMapType::iterator i;
+               for (i = bbGetOutputConnectorMap().begin();
+                    i != bbGetOutputConnectorMap().end();
+                    ++i)
+                 {
+                   i->second->SetChangeTime(t);
+                 }
+               // update the MinOutputChangeTime
+               mMinOutputChangeTime.Set(t);
+             }
+         }
+      }
+  }
+  //=========================================================================
+
+ //=========================================================================
+  ///  Sets the ChangeTime of output 
+  void BlackBox::bbSetOutputChangeTime(BlackBoxOutputConnector* c, 
+                                      const ChangeTime& t)
+  {
+    bbtkDebugMessage("change",1,
+                    "==> BlackBox::bbSetOutputChangeTime("<<c<<","<<t<<") ["
+                    <<bbGetFullName()<<"]"<<std::endl);
+    
+    //ChangeTime old = 
+    c->SetChangeTime(t);
+    // c->GetChangeTime() = t;
+    //    bbUpdateMinOutputChangeTime(t);
+    // propagate
+    
+  }
+  //=========================================================================
+  */
+
+  /*
+  //=========================================================================
+  void BlackBox::bbUpdateMaxInputChangeTime(const ChangeTime& t)
+  {    
+
+    
+    if ( t > mMaxInputChangeTime ) 
+      {
+       mMaxInputChangeTime = t;
+       if ( mMinOutputChangeTime > mMaxInputChangeTime )
+         {
+           
+         }
+      }
+    
+  }
+  //=========================================================================
+
+  //=========================================================================
+  void bbUpdateMinOutputChangeTime(const ChangeTime& t)
+  {
+    ChangeTime old = mMinOutputChangeTime;
+    mMinOutputChangeTime = MAXLONG;
+    OutputConnectorMapType::iterator i;
+    for (i = bbGetOutputConnectorMap.begin();
+        i != bbGetOutputConnectorMap.end();
+        ++i)
+      {
+       if (i->second->GetChangeTime() < mMinOutputChangeTime)
+         mMinOutputChangeTime = i->second->GetChangeTime();
+      }
+    if ( mMinOutputChangeTime < old )
+      {
+      }
+   
+  }
+  //=========================================================================
+  */
+
+  //=========================================================================
+  /// Signals that the BlackBox has been modified through 
+  /// the input connector c
+  /// and propagates it downward
+  /// ** NOT USER INTENDED **
+  void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
+                                        IOStatus s)
+  {
+    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);
+           o->second->SignalChange(GetThisPointer<BlackBox>(),o->first); 
+         }
+      }                                                                        
+    
+    if ( ( bbBoxProcessModeIsReactive()  ||
+          (c==bbGetInputConnectorMap().find("BoxExecute")->second))
+        && (bbCanReact() ) )
+      {
+       bbtkDebugMessage("modified",2,
+                        "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
+        bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
+      }    
+  }
   //=========================================================================
-  ///  Signals that the BlackBox has been modified
+
+  //=========================================================================
+  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,
@@ -477,13 +651,13 @@ namespace bbtk
        this->bbSetStatus(MODIFIED); 
         bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
       }
-    /*
-    else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
-      { 
-       bbtkDebugMessage("modified",2,"-> Already modified"<<std::endl);
-       return;
-      }
-    */
+    
+    //else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
+     // { 
+//     bbtkDebugMessage("modified",2,"-> Already modified"<<std::endl);
+//     return;
//     }
+   
     else 
       {
        bbtkDebugMessage("modified",2,"-> Status set to modified"<<std::endl);
@@ -492,12 +666,11 @@ namespace bbtk
  
     this->bbSignalOutputModification(false);
 
-    /* 
   bbtkDebugMessageDec("process",5,
                        "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
-    */
   }  
+*/
   //=========================================================================
 
   //=========================================================================  
@@ -508,20 +681,16 @@ namespace bbtk
                        <<reaction<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
     
-    OutputConnectorMapType::iterator change = bbGetOutputConnectorMap().end();
     OutputConnectorMapType::iterator i;
     for ( i  = bbGetOutputConnectorMap().begin(); 
-         i != bbGetOutputConnectorMap().end(); ++i) {
-      /*     if ( i->first == "BoxChange" ) 
-       {
-         change = i;
-         continue;
-       }
-      */
-      i->second->SetModifiedStatus();
-    } 
-    //    if (change != bbGetOutputConnectorMap().end()) 
-    // change->second->SetModifiedStatus();
+         i != bbGetOutputConnectorMap().end(); ++i) 
+      {
+       if (i->second->GetStatus()==UPTODATE) 
+         {
+           //      i->second->SetStatus(MODIFIED);
+           i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
+         }
+      } 
 
     if (reaction) bbGlobalProcessExecutionList();
 
@@ -540,28 +709,37 @@ namespace bbtk
                        <<output<<","<<reaction<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
     
-    OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(output);
+    OutputConnectorMapType::iterator i = 
+      bbGetOutputConnectorMap().find(output);
+
+
     if ( i == bbGetOutputConnectorMap().end() ) 
        {
          bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
        }
-    i->second->SetModifiedStatus();
-    // Has to notify the output "BoxChange" also
-    if (output != "BoxChange") 
+
+    if (i->second->GetStatus()==UPTODATE) 
       {
-       i = bbGetOutputConnectorMap().find("BoxChange");
-       if ( i != bbGetOutputConnectorMap().end() ) 
+       //      i->second->SetStatus(MODIFIED);
+       i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
+       // Has to notify the output "BoxChange" also
+       if (output != "BoxChange") 
          {
-           i->second->SetModifiedStatus();
+           i = bbGetOutputConnectorMap().find("BoxChange");
+           if ( i != bbGetOutputConnectorMap().end() ) 
+             {
+               //              i->second->SetStatus(MODIFIED);
+               i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
+             }
          }
+       if (reaction) bbGlobalProcessExecutionList();
       }
-  if (reaction) bbGlobalProcessExecutionList();
-
-  bbtkDebugMessageDec("process",5,
-                      "<= BlackBox::bbSignalOutputModification("
-                      <<output<<") ["
-                      <<bbGetFullName()<<"]"<<std::endl);
 
+    bbtkDebugMessageDec("process",5,
+                       "<= BlackBox::bbSignalOutputModification("
+                       <<output<<") ["
+                       <<bbGetFullName()<<"]"<<std::endl);
+    
   }  
   //=========================================================================   
   //=========================================================================  
@@ -573,6 +751,7 @@ namespace bbtk
                        <<bbGetFullName()<<"]"<<std::endl);
     OutputConnectorMapType::iterator i;
     std::vector<std::string>::const_iterator o;
+    bool changed = false;
     for (o=output.begin();o!=output.end();++o) 
       {
        // the output "BoxChange" must be signaled **AFTER** all others
@@ -583,18 +762,29 @@ namespace bbtk
          {
            bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
          }
-       i->second->SetModifiedStatus();
+       // Already OUTOFDATE : noting to do
+       if (i->second->GetStatus()==UPTODATE)
+         {
+           //  i->second->SetStatus(MODIFIED);
+           i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
+           changed = true;
+         }
       }
     // Has to notify the output "BoxChange" also
     i = bbGetOutputConnectorMap().find("BoxChange");
-    if ( i != bbGetOutputConnectorMap().end() 
+    if ( changed && (i != bbGetOutputConnectorMap().end())
       {
-       i->second->SetModifiedStatus();
+       // Already OUTOFDATE : noting to do
+       if (i->second->GetStatus()==UPTODATE) 
+         {
+           //  i->second->SetStatus(MODIFIED);
+           i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
+           if (reaction) bbGlobalProcessExecutionList();
+         }
       }
-  if (reaction) bbGlobalProcessExecutionList();
 
-   bbtkDebugMessageDec("process",5,
-                      "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
+    bbtkDebugMessageDec("process",5,
+                       "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
                        <<bbGetFullName()<<"]"<<std::endl);
 
   }  
@@ -602,9 +792,9 @@ namespace bbtk
 
   //=========================================================================
   /// Updates the BlackBox inputs
-  /// \returns UPTODATE if all inputs are in UPTODATE status after update
-  ///          else MODIFIED 
-  IOStatus BlackBox::bbUpdateInputs(bool excludeParent)
+  /// Calls BackwardUpdate on all BlackBoxInputConnector
+  /// \returns The maximum of final IOStatus after each input update
+  IOStatus BlackBox::bbUpdateInputs()
   {
     bbtkDebugMessageInc("process",4,
                        "=> BlackBox::bbUpdateInputs() ["
@@ -617,28 +807,54 @@ namespace bbtk
     for ( i = bbGetInputConnectorMap().begin(); 
          i!= bbGetInputConnectorMap().end(); ++i) 
       {
-       if (excludeParent && (i->first=="WinParent")) continue;
-       if (i->first=="WinHide") continue;
+       //      if (i->first=="WinHide") continue;
        // If input type is Void : no recurse
        //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
        //      == typeid(Void) ) 
        //  continue;
-
-       IOStatus t = i->second->BackwardUpdate();
-       if (t==MODIFIED) s = MODIFIED;
+       i->second->BackwardUpdate();
+       IOStatus t = i->second->GetStatus();
+       if (t > s) s = t;
       }
     
-   bbtkDebugMessageDec("process",4,
+    bbtkDebugMessageDec("process",4,
                        "<= BlackBox::bbUpdateInputs() ["
                        <<bbGetFullName()<<"]"
                        <<std::endl);   
-
-
+    
+    
     return s;
   }
   //=========================================================================
 
+  //==================================================================
+  /// Computes the final IOStatus of inputs and outputs after processing
+  void BlackBox::bbComputePostProcessStatus()
+  {
+    IOStatus new_output_status = UPTODATE;
+    if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
+
+    // Update the input statuses
+    InputConnectorMapType::iterator i;
+    for ( i = bbGetInputConnectorMap().begin(); 
+         i!= bbGetInputConnectorMap().end(); ++i) 
+      {
+       IOStatus t = i->second->GetStatus();
+       if (t == OUTOFDATE) new_output_status = OUTOFDATE;
+       // A previously MODIFIED status turns to UPTODATE
+       if (t==MODIFIED) i->second->SetStatus(UPTODATE);
+      }
+
+    // Update the output statuses
+    OutputConnectorMapType::iterator o;
+    for ( o = bbGetOutputConnectorMap().begin(); 
+         o!= bbGetOutputConnectorMap().end(); ++o) 
+      {
+       o->second->SetStatus(new_output_status);
+      }
+  }
+  //==================================================================
+
   //=========================================================================
   /// Connects the input <name> to the connection c
   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
@@ -656,13 +872,19 @@ 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);
     
     bbtkDebugMessage("connection",2,
                        "<== BlackBox::bbConnectInput(\""
                        <<name<<"\","<<c->GetFullName()<<") ["
                        <<bbGetFullName()<<"]"
                        <<std::endl);       
-    //  bbSetModifiedStatus();
 
   }
   //=========================================================================
@@ -869,11 +1091,11 @@ namespace bbtk
     std::string ss("<");
     std::string::size_type pos = 0;
     pos = s.find(ss,0);
-    char* cr = "[";
+    std::string cr("[");
     while ( pos != std::string::npos )
       {
        //      std::cout << "*** find one "<<std::endl;
-       s.replace(pos,1,cr,1);
+       s.replace(pos,1,cr.c_str(),1);
        pos = s.find(ss, pos);
       } 
     ss = ">";
@@ -883,7 +1105,7 @@ namespace bbtk
     while ( pos != std::string::npos )
       {
        //      std::cout << "*** find one "<<std::endl;
-       s.replace(pos,1,cr,1);
+       s.replace(pos,1,cr.c_str(),1);
        pos = s.find(ss, pos);
       } 
     ss = ",";
@@ -893,7 +1115,7 @@ namespace bbtk
     while ( pos != std::string::npos )
       {
        //      std::cout << "*** find one "<<std::endl;
-       s.replace(pos,1,cr,1);
+       s.replace(pos,1,cr.c_str(),1);
        pos = s.find(ss, pos);
       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
   }
@@ -1033,12 +1255,25 @@ namespace bbtk
       {
        bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
       }
+    /*
+    if (bbIsUpToDate())
+      {
+       bbtkMessage("Help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
+                   <<mMinOutputChangeTime<<"]"<<std::endl);
+      }
+    else 
+      {
+       bbtkMessage("Help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
+                   <<mMinOutputChangeTime<<"]"<<std::endl);
+      }
+    */
     //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
     //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
 
     std::vector<std::string> iname;
     std::vector<std::string> ivalue;
     std::vector<std::string> iconn;
+    std::vector<std::string> istatus;
 
     InputConnectorMapType::iterator i;
     unsigned int namelmax = 0;
@@ -1058,11 +1293,13 @@ namespace bbtk
          s += con->GetOriginalBlackBoxFromOutput();
        }  // if con
        iconn.push_back(s);
+       istatus.push_back(GetIOStatusString(i->second->GetStatus()));
       }
     OutputConnectorMapType::iterator o;
     std::vector<std::string> oname;
     std::vector<std::string> ovalue;
     std::vector<std::vector<std::string> > oconn;
+    std::vector<std::string> ostatus;
     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
       {
        oname.push_back(o->first);
@@ -1082,6 +1319,7 @@ namespace bbtk
            ss.push_back(s);
        }  // if con
        oconn.push_back(ss);
+       ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
       }
 
     if (iname.size()) 
@@ -1089,10 +1327,10 @@ namespace bbtk
     else 
       bbtkMessage("Help",1," * No inputs"<<std::endl);
 
-    std::vector<std::string>::iterator i1,i2,i3;
-    for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin();
-        i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end();
-        ++i1,++i2,++i3)
+    std::vector<std::string>::iterator i1,i2,i3,i4;
+    for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
+        i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
+        ++i1,++i2,++i3,++i4)
       {
        std::string name(*i1);
        name += "'";
@@ -1101,9 +1339,11 @@ namespace bbtk
        value += "'";
        value.append(1+valuelmax-value.size(),' ');
        if (i3->size()) 
-         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"<<*i3<<"'"<<std::endl);
+         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"
+                     <<*i3<<"'");
        else 
-         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
+         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value);
+       bbtkMessage("Help",1," ["<<*i4<<"]"<<std::endl);
       }
 
     if (oname.size()) 
@@ -1111,11 +1351,11 @@ namespace bbtk
     else 
       bbtkMessage("Help",1," * No outputs"<<std::endl);
 
-    std::vector<std::vector<std::string> >::iterator i4;
+    std::vector<std::vector<std::string> >::iterator i5;
 
-    for (i1=oname.begin(),i2=ovalue.begin(),i4=oconn.begin();
-        i1!=oname.end(),i2!=ovalue.end(),i4!=oconn.end();
-        ++i1,++i2,++i4)
+    for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
+        i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
+        ++i1,++i2,++i4,++i5)
       {
        std::string name(*i1);
        name += "'";
@@ -1123,17 +1363,18 @@ namespace bbtk
        std::string value(*i2);
        value += "'";
        value.append(1+valuelmax-value.size(),' ');
-       if (!(*i4).size())
-         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
+       if (!(*i5).size())
+         bbtkMessage("Help",1,"    '"<<name<<" = '"<<value);
        else 
          {
            std::string pref = "    '"+name+" = '"+value;
-           for (i3=i4->begin();i3!=i4->end();++i3)
+           for (i3=i5->begin();i3!=i5->end();++i3)
              {
-               bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'"<<std::endl);
+               bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'");
                pref.replace(0,pref.size(),pref.size(),' ');
              }
          }
+       bbtkMessage("Help",1," ["<<*i4<<"]"<<std::endl);
       }
 
    }
index 729365a315d23775c3d2ffd31369a0c05ffad69f..b70ab75f747a07ad0171f1c07025ebaa9ace7853 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBox.h,v $
   Language:  C++
-  Date:      $Date: 2008/12/03 13:35:22 $
-  Version:   $Revision: 1.16 $
+  Date:      $Date: 2008/12/08 12:53:47 $
+  Version:   $Revision: 1.17 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
 #include "bbtkSystem.h"
 #include "bbtkBlackBoxDescriptor.h"
 #include "bbtkBlackBoxInputConnector.h"
-#include "bbtkBlackBoxOutputConnector.h"
+//#include "bbtkBlackBoxOutputConnector.h"
 #include <set>
 
+// Signal/slot mechanism for output change events
+#include <boost/signal.hpp>
+#include <boost/bind.hpp>
+
 namespace bbtk
 {
 
@@ -57,6 +61,7 @@ namespace bbtk
   
   class Factory;
   class Connection;
+  class BlackBoxOutputConnector;
 
   class BBTK_EXPORT BlackBox : public Object
   {
@@ -65,6 +70,12 @@ namespace bbtk
     //==================================================================
     // INTERFACE
     //==================================================================
+    typedef boost::signals::trackable OutputChangeObserverType;
+    typedef boost::signal<void (bbtk::BlackBox::Pointer,
+                               const std::string&,
+                               IOStatus)>  OutputChangeSignalType;
+    typedef OutputChangeSignalType::slot_function_type 
+    OutputChangeCallbackType;
  
     /// The type of map of output connector pointers
     typedef std::map<std::string, BlackBoxOutputConnector*> 
@@ -103,10 +114,25 @@ namespace bbtk
     /// Main processing method of the box.
     virtual void bbExecute(bool force = false);
 
-    ///  Signals that the BlackBox has been modified through the input connector c
-    /// and propagates it downward
-    /// ** NOT USER INTENDED **
-    virtual void bbSetModifiedStatus(BlackBoxInputConnector* c = 0);
+
+    /// The type of callback function when an output changes
+    //   typedef BlackBoxOutputConnector::ChangeCallbackType OutputChangeCallbackType;
+
+    /// Adds the function f to the list of functions to call when 
+    /// the output changes.
+    /// f is of type ChangeCallbackType which is basically:
+    /// void (*ChangeCallbackType)(BlackBoxOutputConnector*)
+    /// To pass a member function 'f' of an instance 'c' of a class 'C' 
+    /// as callback you have to 'bind' it, i.e. call:
+    /// AddChangeObserver ( "Out", boost::bind( &C::f , c, _1 ) );
+    void AddChangeObserver(const std::string& output_name, 
+                          OutputChangeCallbackType f); 
+
+    /// Removes the function f from the list of functions to call when 
+    /// the output changes (TO WRITE)
+    void RemoveChangeObserver(const std::string& output_name, 
+                             OutputChangeCallbackType f); 
+    
 
     /// Signals that the BlackBox outputs have been modified 
     /// (without marking the box as MODIFIED because its output state is ok : don't care if you understand : use it !).
@@ -124,7 +150,7 @@ namespace bbtk
     /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
     /// ** USER INTENDED **
     virtual void bbSignalOutputModification( const std::string& output_name,
-bool reaction = true);
+                                            bool reaction = true);
     /// Signals that the BlackBox vector of outputs "output_name" 
     /// have been modified.
     /// Should be used when more than ONE output is modified but not ALL 
@@ -135,11 +161,12 @@ bool reaction = true);
     /// (after the outputs have been updated of course!)
     /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
     /// ** USER INTENDED **
-    virtual void bbSignalOutputModification( const std::vector<std::string>& output_name,
-bool reaction = true);
+    virtual void bbSignalOutputModification( const std::vector<std::string>& 
+                                            output_name,
+                                            bool reaction = true);
 
     /// Gets the status of the box
-    virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
+    //    virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
 
 
     /// Returns true iff the BlackBox has an input of name label
@@ -158,12 +185,12 @@ bool reaction = true);
     virtual Data bbGetOutput( const std::string &name ) = 0;
 
     /// Sets the data of the input called <name>.
-    /// If setModified is false then does not call bbSetModifiedStatus()
+    /// If update_time is false then does not update ChangeTime of input
     virtual void bbSetInput( const std::string &name, Data data,
-                            bool setModified = true ) = 0;
+                            bool update_time = true ) = 0;
     virtual void bbBruteForceSetInputPointer( const std::string &name, 
                                              void* data, 
-                                             bool setModified = true) =0;
+                                             bool update_time = true) =0;
     ///  Sets the data of the output called <name>
     virtual void bbSetOutput( const std::string &name, Data data) = 0;
 
@@ -180,13 +207,38 @@ bool reaction = true);
     ///  Returns the output connectors map (const)
     const OutputConnectorMapType& bbGetOutputConnectorMap() const 
     { return mOutputConnectorMap; }      
+
+    ///  Returns the input connector
+    BlackBoxInputConnector&  bbGetInputConnector(const std::string& n) 
+    { return *(mInputConnectorMap.find(n)->second); }
+    ///  Returns the output connector
+    BlackBoxOutputConnector& bbGetOutputConnector(const std::string& n) 
+    { return *(mOutputConnectorMap.find(n)->second); }
+    ///  Returns the input connector (const)
+    const BlackBoxInputConnector&  bbGetInputConnector(const std::string& n) const
+    { return *(mInputConnectorMap.find(n)->second); }
+    ///  Returns the output connector (const)
+    const BlackBoxOutputConnector& bbGetOutputConnector(const std::string& n) const 
+    { return *(mOutputConnectorMap.find(n)->second); }
+
  
+    
 
     /// Prints the Help on the BlackBox type 
     virtual void bbGetHelp(bool full=true) const;
 
 
-    //==================================================================
+    // Returns true iff the box is up-to-date 
+    // (ChangeTime of inputs are all lower strictly to ChangeTime of outputs -
+    //  i.e. max(inputs)<=min(outputs) )
+    //   bool bbIsUpToDate() { return mMaxInputChangeTime < mMinOutputChangeTime; }
+    // Returns true iff the box is out-of-date 
+    // (At least one ChangeTime of an input is greater than one ChangeTime 
+    //  of an output - i.e. max(inputs)>min(outputs))
+    // == !IsUpToDate()
+    //    bool bbIsOutOfDate() { return mMaxInputChangeTime >= mMinOutputChangeTime; }
+
+   //==================================================================
     // Common inputs / outputs to all boxes
     /// Returns the value of the input "BoxProcessMode"
     std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
@@ -214,7 +266,7 @@ bool reaction = true);
     /// Returns the value of the output "Change"
     Void bbGetOutputBoxChange() { return Void(); }
     /// Sets the value of the output "Change" : signal a modification
-    void bbSetOutputBoxChange(Void = 0) { bbSetModifiedStatus(); }
+    void bbSetOutputBoxChange(Void = 0) { } //bbSetModifiedStatus(); }
 
     //==================================================================    
 
@@ -275,11 +327,20 @@ bool reaction = true);
 
 
     //==================================================================
-    ///  Sets the status of the box
-    void bbSetStatus( IOStatus t) { bbmStatus = t; } 
+    /// Signals that the input whose connector is c has changed 
+    /// and propagates the info downward
+    /// ** NOT USER INTENDED **
+    virtual void bbSetStatusAndPropagate(BlackBoxInputConnector* c,
+                                        IOStatus s);
+    /// Signals that the output whose connector is c has changed 
+    /// and propagates the info downward
+    /// ** NOT USER INTENDED **
+    virtual void bbSetStatusAndPropagate(BlackBoxOutputConnector* c,
+                                        IOStatus s);
     //==================================================================
     
   private:
+    //==================================================================
     friend class Connection;
     friend class ComplexBlackBox;
 
@@ -300,61 +361,39 @@ bool reaction = true);
     virtual void bbDisconnectOutput( const std::string& name, 
                                     Connection* c);
 
-
+    //==================================================================
+  protected: 
     /// @name Pipeline processing methods
-    ///  Methods which participate to (forward or backward) pipeline processing.
-    ///  Some are pure virtual and prepare particular update mechanism which are implemented by descendents (e.g. ForwardUpdate and UpdateChildren are made for WxContainerBlackBox particular update mechanism which must recurse a piece of the pipeline top-down).
+    ///  Methods which participate to pipeline processing.
+    ///  Some are pure virtual and prepare particular update mechanism which are implemented by descendents 
     /// The main method is bbBackwardUpdate which is called by bbExecute and implemented in UserBlackBox and ComplexBlackBox.
     /// 
     //@{
 
+    
     //==================================================================   
     /// Recursive pipeline processing in backward direction 
-    /// (recursion is in backward direction however execution always goes forward).
-    /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
+    /// (recursion is in backward direction however execution always 
+    /// goes forward).
+    /// Pure virtual; defined in AtomicBlackBox and ComplexBlackBox
     /// 
-    /// \returns The final status of the box (UPTODATE or MODIFIED)
     /// \param caller : The connection which invoked the method; null if called by bbExecute
-    ///
-    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
-    /// then : 
-    /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on upstream boxes)
-    /// - calls bbCreateWidget
-    /// - calls bbProcess which is the user callback which does the actual processing
-    /// - calls bbUpdateChildren
-    /// - calls bbShowWidget which shows the widget associated to the box (if any)
-  protected:
-    virtual IOStatus bbBackwardUpdate(Connection::Pointer caller) = 0;
+    virtual void bbBackwardUpdate(Connection::Pointer caller) = 0;
     //==================================================================
-
-    //==================================================================
-    /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
-    /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
-    /// 
-    /// \param caller : The connection which invoked the method
-    ///
-    /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
-    /// then : 
-    /// - calls bbCreateWidget
-    /// - calls bbProcess which is the user callback which does the actual processing
-    /// - calls bbUpdateChildren which recursively calls bbForwardUpdate on connections attached the "Child" output
-    // virtual void bbForwardUpdate(Connection::Pointer caller) = 0;
-    //==================================================================
-  protected:
+    
     //==================================================================
-    /// Updates the BlackBox inputs and returns the final status of the inputs 
-    /// (==UPTODATE iff all inputs are UPTODATE)  
-    // If excludeParent == true then excludes the upstream box connected to input 'Parent' from recursive update
-    IOStatus bbUpdateInputs(bool excludeParent=false);
+    /// Updates the BlackBox inputs
+    /// Calls BackwardUpdate on all BlackBoxInputConnector
+    /// \returns The maximum of final IOStatus after each input update
+    IOStatus bbUpdateInputs();
     //==================================================================
 
     //==================================================================
-    /// Updates the pipeline in upstream-downstream direction along the "Child"-"Parent" connections only.
-    /// Does nothing here. Overloaded in WxContainerBlackbox
-    //virtual void bbUpdateChildren( Connection::Pointer caller ) { }
+    /// Computes the final IOStatus of inputs and outputs after processing
+    void bbComputePostProcessStatus();
     //==================================================================
 
     //==================================================================
     /// Specific methods for window creation during pipeline execution
     /// Creates the window associated to the box (called after bbUpdateInputs)
@@ -402,6 +441,7 @@ bool reaction = true);
     virtual void bbCopyIOValues(BlackBox& from);
     //==================================================================
 
+    //==================================================================
     // Black box objects have a special deleter 
     // which must take care of releasing the descriptor 
     // **AFTER** the box is deleted 
@@ -414,33 +454,40 @@ bool reaction = true);
       Deleter();
       void Delete(Object* p);
     };
+    //==================================================================
 
+    //==================================================================
     template <class U>
     static boost::shared_ptr<U> MakeBlackBoxPointer(U* s, bool lock = false)
     {
       return MakePointer(s,BlackBox::Deleter(),lock);
     }
+    //==================================================================
 
+    //==================================================================
     virtual void bbDelete() { delete this; }
+    //==================================================================
+
+
+    //==================================================================
   private:
-    
+    //==================================================================
  
     //==================================================================
-    // PRIVATE PART 
+    // ATTRIBUTES
     /// The status of the box
-    IOStatus bbmStatus;
+    //    IOStatus bbmStatus;
     /// Is the box executing ?
     bool bbmExecuting;
     /// The name of the black-box
     std::string bbmName;
     /// The name of the package to which it belongs
     std::string bbmPackageName;
-       
-    /// 0 : "Pipeline" mode : bbBackwardUpdate() only calls Process if Status == MODIFIED (normal pipeline processing)
-    /// 1 : "Always" mode : bbUpdate() always calls Process  
-    /// 2 : "Reactive" mode : bbSetModifiedStatus() calls bbUpdate()
+    /// The box processing mode
+    /// 0 : "Pipeline" mode 
+    /// 1 : "Always" mode 
+    /// 2 : "Reactive" mode 
     std::string bbmBoxProcessMode;
-
     /// The parent of the black box in the ComplexBlackBox hierarchy
     BlackBox::WeakPointer bbmParent;
     //==================================================================
@@ -454,6 +501,31 @@ bool reaction = true);
     InputConnectorMapType mInputConnectorMap;
     //==================================================================
 
+    /// The maximum ChangeTime of the inputs
+    //    ChangeTime mMaxInputChangeTime;
+    /// The minimum ChangeTime of the outputs
+    //    ChangeTime mMinOutputChangeTime;
+
+
+  protected:
+    //=========================================================================
+    ///  Sets the ChangeTime of input 
+    /*
+    void bbSetInputChangeTime(BlackBoxInputConnector* c, 
+                             const ChangeTime& t);
+    ///  Sets the ChangeTime of output 
+    void bbSetOutputChangeTime(BlackBoxOutputConnector* c, 
+                              const ChangeTime& t);
+    */
+    //   void bbUpdateMaxInputChangeTime(const ChangeTime& t);
+    //    void bbUpdateMinOutputChangeTime(const ChangeTime& t);
+
+    ///  Set the change time of the input 
+    //    void bbSetInputChangeTime(const std::string& n, ChangeTime);
+    ///  Set the change time of the output 
+    //    void bbSetOutputChangeTime(const std::string& n, ChangeTime);
+
+
 
  };
   // Class BlackBox
index c9371af4007048b7c7787290dff95fab3cb62fd1..f980cc3470f8324908baeece6d7d44b3ae707ae1 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBoxInputConnector.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:12 $
-  Version:   $Revision: 1.6 $
+  Date:      $Date: 2008/12/08 12:53:50 $
+  Version:   $Revision: 1.7 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
 
 namespace bbtk
 {
+  //========================================================================
   BlackBoxInputConnector::BlackBoxInputConnector(BlackBox::Pointer b)  
     : mBox(b), mConnection(0), mStatus(MODIFIED)
   {
     bbtkDebugMessage("Kernel",9,"BlackBoxInputConnector::BlackBoxInputConnector()"<<std::endl);
   }
+  //========================================================================
 
-
+  //========================================================================
   BlackBoxInputConnector::~BlackBoxInputConnector() 
   {
     bbtkDebugMessageInc("Kernel",9,"BlackBoxInputConnector::~BlackBoxInputConnector()"<<std::endl);
     bbtkDebugDecTab("Kernel",9);
   }
-  
+  //========================================================================
+
+  //========================================================================
   void BlackBoxInputConnector::SetConnection(Connection* c) 
   { 
     bbtkDebugMessage("Kernel",9,"BlackBoxInputConnector::SetConnection("<<c<<")"<<std::endl);
     mConnection = c; 
   }
-  
+  //========================================================================
+
+  //========================================================================
   void BlackBoxInputConnector::UnsetConnection(Connection* c) 
   { 
     bbtkDebugMessage("Kernel",9,"BlackBoxInputConnector::UnsetConnection("
                     <<c<<")"<<std::endl);
-    mConnection = 0; //.reset();
+    mConnection = 0; 
   }
+  //========================================================================
   
-  IOStatus BlackBoxInputConnector::BackwardUpdate()
+  //========================================================================
+  void BlackBoxInputConnector::BackwardUpdate()
   {
     bbtkDebugMessage("process",9,"==> BlackBoxInputConnector::BackwardUpdate()"
                     <<std::endl);
 
-    if (mConnection) //.lock()) 
-      {
-       IOStatus s = mConnection->BackwardUpdate();
-       mStatus = s;
-      }
-    else 
+    // If UPTODATE or MODIFIED : nothing to do
+    //  if (mStatus != OUTOFDATE) return;
+
+    // If connected and OUTOFDATE : recursive update
+    // Post-update status is updated by the connection 
+    // (either MODIFIED or OUTOFDATE)
+    if ( mConnection && (mStatus == OUTOFDATE) )
       {
-       mStatus = UPTODATE;
+       mConnection->BackwardUpdate();
       }
-
-    return mStatus;
-
+    // If not connected : it was set to OUTOFDATE on creation
+    // Becomes MODIFIED
+    // LGTODO : Initialize to MODIFIED and set to OUTOFDATE on connection ?
+    //   else 
+    //      {
+    // mStatus = MODIFIED;
+    //    }
   }
+  //========================================================================
 
-
-  //    void Modified();
-  
 }
 // namespace bbtk
 
index d8cd58c56ba0d38dd207a3efc124c8e3649b1ada..05e414fbb56852cfab38763f417cb8358d1df429 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBoxInputConnector.h,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:12 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2008/12/08 12:53:56 $
+  Version:   $Revision: 1.5 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -42,6 +42,7 @@
 #define __bbtkBlackBoxInputConnector_h__
 
 #include "bbtkConnection.h"
+#include "bbtkChangeTime.h"
 #include <vector>
 
 namespace bbtk
@@ -64,23 +65,51 @@ namespace bbtk
     /// The parameter is USELESS today but would be useful if we allow multiple connections on inputs
     void UnsetConnection(Connection* c);
   
-    IOStatus BackwardUpdate();
+    //    IOStatus 
+    void BackwardUpdate();
+
+    /// Returns the ChangeTime of the output (const)
+    // const ChangeTime& GetChangeTime() const { return mChangeTime; }
+    /// Returns the ChangeTime of the output 
+    // ChangeTime& GetChangeTime() { return mChangeTime; }
+    //   bool SetChangeTime(const ChangeTime& t) { return mChangeTime.Set(t); }
 
     /// Returns the connection plugged into this input (const)
     Connection* GetConnection() const { return mConnection; }
     /// Returns true iff a connection is connected to it
     bool IsConnected() const { return (mConnection != 0); }
-    /// Returns the status of the input (UPTODATE | MODIFIED)
-    const IOStatus& GetStatus() const { return mStatus; }
-    ///
+    
+
+    /// Returns the status of the input 
+    IOStatus GetStatus() const { return mStatus; }
+    /// Sets the status of the input 
+    void SetStatus(IOStatus s) { mStatus = s; }
+    
+    
+
+    /// Returns the black box which owns the connector
     BlackBoxPointer GetBlackBox() const { return mBox.lock(); } 
   private:
     /// 
     BlackBoxWeakPointer mBox;
     /// The connection plugged into the input
     Connection* mConnection;
-    /// The status of the input (UPTODATE | MODIFIED)
+    /// The status of the input (UPTODATE | MODIFIED | OUTOFDATE)
     IOStatus mStatus;
+   // The change time
+    //   ChangeTime mChangeTime;
+
+    /*
+    /// Returns the TimeStamp
+    const TimeStamp& GetTimeStamp() const { return mTimeStamp;}
+    TimeStamp& GetTimeStamp() { return mTimeStamp;}
+    /// Set the connector to MODIFIED status and increments the time stamp
+    void SetModified() 
+    { mStatus = MODIFIED; mTimeStamp.Modified(); }
+    /// The TimeStamp
+    TimeStamp mTimeStamp;
+    */
   };
   
 }
index b09f262d046e8305318f5081cd994c778213218c..8024663d81f4734857e704d718bfea3bdf893b94 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBoxOutputConnector.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:12 $
-  Version:   $Revision: 1.8 $
+  Date:      $Date: 2008/12/08 12:54:00 $
+  Version:   $Revision: 1.9 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
 namespace bbtk
 {
 
+  //======================================================================
   BlackBoxOutputConnector::BlackBoxOutputConnector() 
-  // : mStatus(MODIFIED)
+    : mStatus(OUTOFDATE)
   {
     bbtkDebugMessage("Kernel",9,"BlackBoxOutputConnector::BlackBoxOutputConnector()"<<std::endl);
   }
+  //======================================================================
 
+
+  //======================================================================
   BlackBoxOutputConnector::~BlackBoxOutputConnector() 
   {
     bbtkDebugMessage("Kernel",9,
@@ -65,18 +69,21 @@ namespace bbtk
                     "<== BlackBoxOutputConnector::~BlackBoxOutputConnector()"
                     <<std::endl);
   }
+  //======================================================================
 
+  //======================================================================
   ///
   void BlackBoxOutputConnector::SetConnection(Connection* c)
   {
     bbtkDebugMessage("Kernel",9,"BlackBoxOutputConnector::SetConnection("
                     <<c<<")"<<std::endl);
     mConnection.push_back(c);
+    //    AddChangeObserver(boost::bind(&Connection::SignalChange,c));
   }
+  //======================================================================
 
 
-
-  ///
+  //======================================================================
   void BlackBoxOutputConnector::UnsetConnection(Connection* c)
   {
     bbtkDebugMessageInc("Kernel",9,"BlackBoxOutputConnector::UnsetConnection("
@@ -102,12 +109,35 @@ namespace bbtk
        bbtkInternalError("BlackBoxOutputConnector::UnsetConnection("<<c<<") : connection is absent from connections list");
       }
     mConnection.erase(i);
+    //    RemoveChangeObserver(boost::bind(&Connection::SignalChange,c));
 
     bbtkDebugDecTab("Kernel",9);
   }
-
+  //======================================================================
 
   
+   //======================================================================
+  void BlackBoxOutputConnector::SignalChange( BlackBox::Pointer box,
+                                             const std::string& output )
+  {
+    bbtkDebugMessage("change",2,
+                    "==> BlackBoxOutputConnector::SignalChange("
+                    <<box->bbGetFullName()<<",'"
+                    <<output<<"','"<<GetIOStatusString(mStatus)<<"') ["
+                    <<this<<"]"
+                    <<std::endl);
+
+    mChangeSignal(box,output,mStatus);
+
+    bbtkDebugMessage("change",2,
+                    "<== BlackBoxOutputConnector::SignalChange("
+                    <<box->bbGetFullName()<<",'"
+                    <<output<<"','"<<GetIOStatusString(mStatus)<<"') ["
+                    <<this<<"]"
+                    <<std::endl);
+  }
+  //======================================================================
+ /*
   void BlackBoxOutputConnector::SetModifiedStatus()
   {
     bbtkDebugMessage("modified",2,
@@ -122,9 +152,63 @@ namespace bbtk
     
     
    }
+  */
+  /*
+  //======================================================================
+  void BlackBoxOutputConnector::SetChangeTime(const ChangeTime& t)
+  {
+    bbtkDebugMessage("change",2,
+                    "==> BlackBoxOutputConnector::SetChangeTime("<<t<<") ["
+                    <<this<<"]"
+                    <<std::endl);
+    if (mChangeTime.Set(t))
+      {
+       mChangeSignal(this);
+      }
+    bbtkDebugMessage("change",2,
+                    "<== BlackBoxOutputConnector::SetChangeTime("<<t<<") ["
+                    <<this<<"]"
+                    <<std::endl);
+  }
+  //======================================================================
+  */
+  /*
+ //======================================================================
+  void BlackBoxOutputConnector::SetChangeTimeToCurrentTime()
+  {
+    bbtkDebugMessage("change",2,
+                    "==> BlackBoxOutputConnector::SetChangeTimetoCurrentTime() ["
+                    <<this<<"]"
+                    <<std::endl);
+    mChangeTime.Set(ChangeTime::GetCurrentTime());
+    mChangeSignal(this);
+    
+    bbtkDebugMessage("change",2,
+                    "<==> BlackBoxOutputConnector::SetChangeTimetoCurrentTime() ["
+                    <<this<<"]"
+                    <<std::endl);
+  }
+  //======================================================================
+  */
 
 
+  //======================================================================
+  void BlackBoxOutputConnector::AddChangeObserver(OutputChangeCallbackType f)
+  { 
+    mChangeSignal.connect(f); 
+  }
+  //======================================================================
+  
+  //======================================================================
+  /// Removes the function f from the list of functions to call when 
+  /// the output changes (TO WRITE)
+  void BlackBoxOutputConnector::RemoveChangeObserver(OutputChangeCallbackType f)
+  { 
+    bbtkError("BlackBoxOutputConnector::RemoveChangeObserver not implemented");
+    
+    //mChangeSignal.disconnect(f);
+  }
+  //======================================================================
 }
 // namespace bbtk
 
index c97cdc55e939434096bd992897738d7629b5f249..d94b481dfcc59a4eb5f4e530cb93549a717906b4 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBoxOutputConnector.h,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:12 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2008/12/08 12:54:06 $
+  Version:   $Revision: 1.5 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
 #define __bbtkBlackBoxOutputConnector_h__
 
 #include "bbtkConnection.h"
+#include "bbtkBlackBox.h"
 #include "bbtkMessageManager.h"
 #include <vector>
 
+// Change time management
+//#include <bbtkChangeTime.h>
+
+// Signal/slot mechanism for output change events
+//#include <boost/signal.hpp>
+//#include <boost/bind.hpp>
+
 namespace bbtk
 {
 
+  //  class BlackBox;
+  //  BBTK_FORWARD_DECLARE_POINTER(BlackBox);
 
+  //  void  operator (void*)(ChangeCallbackType t) { return (void*)t; };
+/*
+  typedef void (*ChangeSignalFunctionType)(BlackBoxOutputConnector*);
+  bool operator==(void (*sg1)(BlackBoxOutputConnector*),
+                 void (*sg2)(BlackBoxOutputConnector*)) 
+  { return sg1==sg2;}
+*/
+/*
+  bool operator==(boost::function1<void, bbtk::BlackBoxOutputConnector*, std::allocator<void> >,boost::function1<void, bbtk::BlackBoxOutputConnector*, std::allocator<void> >)
+  {
+  }
+*/
+  //boost::function<void ()(bbtk::BlackBoxOutputConnector*), std::allocator<void> >]
   class BBTK_EXPORT BlackBoxOutputConnector 
   {
   public:
-     
+    //    typedef boost::signals::trackable ChangeObserverType;
+    //    typedef boost::signal<void (bbtk::BlackBox::Pointer*,const std::string&,IOStatus)>  ChangeSignalType;
+    //    typedef ChangeSignalType::slot_function_type ChangeCallbackType;
+
+    typedef BlackBox::OutputChangeCallbackType OutputChangeCallbackType;
+
     BlackBoxOutputConnector();
     ~BlackBoxOutputConnector();
+
     void SetConnection(Connection* c);
     void UnsetConnection(Connection* c);
-    //IOStatus Update();
-    void SetModifiedStatus();
     typedef std::vector<Connection*> ConnectionVector;
     const ConnectionVector& GetConnectionVector() const { return mConnection; }
     
+    IOStatus GetStatus() const { return mStatus; }
+    void SetStatus( IOStatus s ) { mStatus = s; }
+    void SignalChange( BlackBox::Pointer box, const std::string& output );
+
+
+    //    void SetModifiedStatus();
+
+    /// Returns the ChangeTime of the output (const)
+    //  const ChangeTime& GetChangeTime() const { return mChangeTime; }
+    /// Returns the ChangeTime of the output 
+    //    ChangeTime& GetChangeTime() { return mChangeTime; }
+
+    /// To be called when the output has changed
+    /// (sets the ChangeTime to current time and 
+    ///  signals the change to observers)
+    //    void SetChangeTime(const ChangeTime&); 
+   
+    /// To be called when the output has changed
+    /// (sets the ChangeTime to current time and 
+    ///  signals the change to observers)
+    //    void SetChangeTimeToCurrentTime(); 
+
+    /// Adds the function f to the list of functions to call when 
+    /// the output changes.
+    /// f is of type ChangeCallbackType which is basically:
+    /// void (*ChangeCallbackType)(BlackBoxOutputConnector*)
+    /// To pass a member function 'f' of an instance 'c' of a class 'C' 
+    /// as callback you have to 'bind' it, i.e. call:
+    /// AddChangeObserver ( boost::bind( &C::f , c, _1 ) );
+    void AddChangeObserver(OutputChangeCallbackType f); 
+
+    /// Removes the function f from the list of functions to call when 
+    /// the output changes (TO WRITE)
+    void RemoveChangeObserver(OutputChangeCallbackType f); 
+
+
   private:
     /// The vector of output connections
     ConnectionVector mConnection;
     /// The status of the output 
-    //IOStatus mStatus;
+    IOStatus mStatus;
+
+    BlackBox::OutputChangeSignalType mChangeSignal;
+
+    // The change time
+    ChangeTime mChangeTime;
   };
   
 }
index a8653ccedbe769f10698b804d512c39291f28b20..de9bb69e41cb1e154bb38c60899a1677c2a895fd 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkComplexBlackBox.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:12 $
-  Version:   $Revision: 1.21 $
+  Date:      $Date: 2008/12/08 12:54:09 $
+  Version:   $Revision: 1.22 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -279,6 +279,7 @@ namespace bbtk
   }
   //==================================================================
 
+  /*
   //==================================================================
   void ComplexBlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
   {
@@ -288,13 +289,9 @@ namespace bbtk
 
     c->GetBlackBox()->bbSetModifiedStatus(c);
 
-    /*
-    bbtkDebugMessage("modified",1,
-                    "<== ComplexBlackBox::bbSetModifiedStatus("
-                    <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
-    */
   }
   //==================================================================
+*/
 
   //==================================================================
   void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
@@ -312,7 +309,7 @@ namespace bbtk
   //==================================================================
 
   //==================================================================
-  IOStatus ComplexBlackBox::bbBackwardUpdate(Connection::Pointer caller)
+  void ComplexBlackBox::bbBackwardUpdate(Connection::Pointer caller)
   {
     bbtkDebugMessageInc("process",3,
                        "==> ComplexBlackBox::bbBackwardUpdate("
@@ -334,7 +331,7 @@ namespace bbtk
       
 
 
-    IOStatus s = UPTODATE;
+    //    IOStatus s = UPTODATE;
     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
       = bbGetDescriptor()->GetOutputDescriptorMap(); 
     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator i 
@@ -360,21 +357,22 @@ namespace bbtk
        //Connection newcaller(*caller);
        //newcaller.SetBlackBoxFromOutput(d->GetOutput());
        //IOStatus s1 = b->bbBackwardUpdate(&newcaller);
-       IOStatus s1 = b->bbBackwardUpdate(caller);
+       //IOStatus s1 =
+       b->bbBackwardUpdate(caller);
        //newcaller.Clear();
        // restore old output
        //      caller->SetBlackBoxFromOutput(oldout);
 
        // ??? STATUS OF CBBs ???
        // ??? Here it is only the final status of the boxes connected to the output 
-       if (s1==MODIFIED) s=MODIFIED;
+       //      if (s1==MODIFIED) s=MODIFIED;
       }
     else 
       {
        bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid output of the complex box !");
       }
 
-    return s;
+    return; // s;
     
   }
   //==================================================================
index ef9fc415b7f723f7c52d63df84393bab3bc61f0c..cf4000fbd5e0b4c6bac2bce1e51c9d22a48001fa 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkComplexBlackBox.h,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:12 $
-  Version:   $Revision: 1.5 $
+  Date:      $Date: 2008/12/08 12:54:13 $
+  Version:   $Revision: 1.6 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -153,9 +153,10 @@ namespace bbtk
     ComplexBlackBox(ComplexBlackBox& from, const std::string &name);
     
   public:
-    IOStatus bbBackwardUpdate(Connection::Pointer caller);
+    //IOStatus 
+    void bbBackwardUpdate(Connection::Pointer caller);
     //  void bbForwardUpdate(Connection* caller);
-    void bbSetModifiedStatus(BlackBoxInputConnector* c);
+    //    void bbSetModifiedStatus(BlackBoxInputConnector* c);
 
   protected:
   
index 0b8fb9c11dc890b0ee3ffe9b5a24d491a9828e07..51538159f28d03e9d3981c014f53104e1ecbde7b 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkConnection.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/10/17 08:18:13 $
-  Version:   $Revision: 1.15 $
+  Date:      $Date: 2008/12/08 12:54:19 $
+  Version:   $Revision: 1.16 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
 #include "bbtkFactory.h"
 #include "bbtkBlackBox.h"
 #include "bbtkMessageManager.h"
+#include "bbtkBlackBoxOutputConnector.h"
 
 namespace bbtk
 {
+  const std::string IOSTATUS_STRING[3] = 
+    {"Up-to-date","Modified","Out-of-date"}; 
+  
+  const std::string& GetIOStatusString(IOStatus s)
+  { return IOSTATUS_STRING[s]; }
+
   //==================================================================
   Connection::Pointer Connection::New(BlackBox::Pointer from, 
                                      const std::string& output,
@@ -160,6 +167,8 @@ Connection::Connection(BlackBox::Pointer from, const std::string& output,
     //Pointer p = MakePointer(this,true);
     from->bbConnectOutput(output,this);
     to->bbConnectInput(input,this);
+    from->bbGetOutputConnector(output).AddChangeObserver(boost::bind(&bbtk::Connection::OnOutputChange,this, _1, _2, _3));
 
     
     bbtkDebugMessage("connection",1,"<== Connection::Connection(\""
@@ -278,6 +287,7 @@ Connection::Connection(BlackBox::Pointer from, const std::string& output,
     from->bbConnectOutput(output,this);
     to->bbConnectInput(input,this);
 
+    from->bbGetOutputConnector(output).AddChangeObserver(boost::bind(&bbtk::Connection::OnOutputChange,this, _1, _2, _3));
     
     bbtkDebugMessage("connection",1,"<== Connection::Connection(\""
                     <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
@@ -329,23 +339,26 @@ Connection::Connection(BlackBox::Pointer from, const std::string& output,
   
   //==================================================================
   /// Backward Update
-  IOStatus Connection::BackwardUpdate()
+  void Connection::BackwardUpdate()
   {
     bbtkDebugMessage("process",5,
                     "===> Connection::BackwardUpdate() ["
                     <<GetFullName()<<"]"<<std::endl);
 
-    IOStatus s = UPTODATE;
-    s = mFrom->bbBackwardUpdate(GetThisPointer<Connection>());
+    mFrom->bbBackwardUpdate(GetThisPointer<Connection>());
 
     TransferData();
 
-    if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
+    // Transfer status
+    IOStatus s = MODIFIED;
+    if ( mFrom->bbGetOutputConnector(mOutput).GetStatus() == OUTOFDATE) 
+      s = OUTOFDATE,
+    mTo->bbGetInputConnector(mInput).SetStatus(s);
 
     bbtkDebugMessage("process",5,
                     "<=== Connection::BackwardUpdate() ["
                     <<GetFullName()<<"]"<<std::endl);
-    return s;
+    return; // s;
   }
   //==================================================================
 
@@ -481,6 +494,7 @@ Connection::Connection(BlackBox::Pointer from, const std::string& output,
   }
   //==================================================================
   
+  /*
   //==================================================================
   /// Modified
   void Connection::SetModifiedStatus()
@@ -493,11 +507,28 @@ Connection::Connection(BlackBox::Pointer from, const std::string& output,
     
     mTo->bbSetModifiedStatus(  mTo->bbGetInputConnectorMap().find(mInput)->second );
     
-    /*
-    bbtkDebugMessage("modified",2,
-                    "==> Connection::SetModifiedStatus() ["
+  }
+  //==================================================================
+  */
+  //==================================================================
+  /// From.Output change propagation
+  void Connection::OnOutputChange(bbtk::BlackBox::Pointer, const std::string&, 
+                                 IOStatus status)
+  {
+    bbtkDebugMessage("change",2,
+                    "==> Connection::OnOutputChange("<<status<<") ["
                     <<GetFullName()<<"]"<<std::endl);
-    */
+    
+    if (mAdaptor) 
+      {
+       BlackBoxInputConnector* ac = mAdaptor->bbGetInputConnectorMap().find("In")->second;
+       mAdaptor->bbSetStatusAndPropagate(ac,status);
+      }
+    
+    mTo->bbSetStatusAndPropagate( mTo->bbGetInputConnectorMap().find(mInput)->second, status);
+    
   }
   //==================================================================
 
index 2b1fe73d680ac0182199c16703eeb17fc7c1aea6..649b6eff5d8b48d27cf6a6323b98fd89c1149d5a 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkConnection.h,v $
   Language:  C++
-  Date:      $Date: 2008/11/13 14:46:43 $
-  Version:   $Revision: 1.9 $
+  Date:      $Date: 2008/12/08 12:54:23 $
+  Version:   $Revision: 1.10 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -56,14 +56,16 @@ namespace bbtk
   class BlackBoxInputConnector;
   class BlackBoxOutputConnector;
 
-  /// 
-  typedef int IOStatus;
-  /// 
-  const int MODIFIED = 0;
-  /// 
-  const int UPTODATE = 1;
-  /// OBSOLETE 
-  ///  const int UPDATING = 2;
+  /// The type of input / output status 
+  typedef unsigned char IOStatus;
+  /// Up-to-date status value
+  const IOStatus UPTODATE  = 0;
+  /// Modified status value
+  const IOStatus MODIFIED  = 1;
+  /// Out-of-date status value
+  const IOStatus OUTOFDATE = 2;
+
+  const std::string& GetIOStatusString( IOStatus );
 
 
   class BBTK_EXPORT Connection : public Object
@@ -82,17 +84,18 @@ namespace bbtk
 
     // void Delete();
     
-    /// Amont direction pipeline processing
-    /// 1) call bbBackwardUpdate(this) on the upstream box
-    /// 2) copies the upstream box output to the downstream box input adapting it if needed
-    virtual IOStatus BackwardUpdate();
-
-    /// Aval direction pipeline processing :
-    /// 1) copies the upstream box output to the downstream box input adapting it if needed
-    /// 2) call bbForwardUpdate(this) on the downstream box
-    //    virtual void ForwardUpdate();
+    /// Pipeline processing method
+    /// 1) call bbBackwardUpdate(this) on the from box
+    /// 2) copies the from box output to the to box input 
+    ///    adapting it if needed
+    /// 3) sets the new IOStatus of the to box input to the 
+    ///    status of the from box output
+    void BackwardUpdate();
+    
+    /// Change callback
+    void OnOutputChange(BlackBoxPointer, const std::string&, 
+                       IOStatus);
 
-    virtual void SetModifiedStatus();
     std::string GetFullName() const; 
 
     /// Returns the original initial black box of the connection
index 99a0da480292be5bc98768ff481a1d428c7975d1..f0237f9a8b3ccbe16c7e094c9c341ff4475a06d1 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkKWBlackBox.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/12/03 09:38:02 $
-  Version:   $Revision: 1.5 $
+  Date:      $Date: 2008/12/08 12:54:26 $
+  Version:   $Revision: 1.6 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
 
  
 #include "bbtkKWBlackBox.h"
+#include "bbtkBlackBoxOutputConnector.h"
 #include "vtkKWBlackBoxDialog.h"
 
 
 namespace bbtk
 {
 
-
-
-  /*
-  //=========================================================================
-  // KWBlackBoxWidgetEventHandler
-  //=========================================================================
-
-  //=========================================================================
-  KWBlackBoxWidgetEventHandler::
-  KWBlackBoxWidgetEventHandler( KWBlackBox::Pointer box, 
-                               vtkKWWidget *widget )
-    :
-    mBox(box),
-    mWindow(widget)
-  { 
-    bbtkDebugMessage("kw",9,"KWBlackBoxWidgetEventHandler::KWBlackBoxWidgetEventHandler("<<mBox.lock()->bbGetFullName()<<")"<<std::endl);
-
-    mBox.lock()->bbSetWidgetEventHandler(this);
-
-    Connect (  mWindow->GetId(),
-              kwEVT_DESTROY,
-              (kwObjectEventFunction) 
-              (void (kwEvtHandler::*)(kwWindowDestroyEvent& c))
-               &KWBlackBoxWidgetEventHandler::OnWindowDestroy );
-    
-    mWindow->PushEventHandler(this);
-    
-  }
-  //=========================================================================
-
-  //=========================================================================
-  KWBlackBoxWidgetEventHandler::~KWBlackBoxWidgetEventHandler()
-  {
-    if (mBox.expired()) return;
-    bbtkDebugMessage("kw",9,
-                    "KWBlackBoxWidgetEventHandler::~KWBlackBoxWidgetEventHandler() ["
-                    <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
-     mBox.lock()->bbSetWidgetEventHandler(0);   
-  }
-  //=========================================================================
-
-  //=========================================================================
-  void KWBlackBoxWidgetEventHandler::OnWindowDestroy(kwWindowDestroyEvent&)
-  {
-    if (mBox.expired()) return;
-    bbtkDebugMessage("kw",9,"KWBlackBoxWidgetEventHandler::OnWindowDestroy() ["
-                    <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
-    mBox.lock()->bbSetOutputWidget(0);
-    mBox.lock()->bbSetModifiedStatus();
-  }
-  //=========================================================================
-
-
-  */
-
-
-
-
   //=========================================================================
   // KWBlackBox
   //=========================================================================
@@ -163,7 +106,7 @@ namespace bbtk
     bbSetOutputWidget(0);
 
     //    bbSetWidgetEventHandler(0);
-    bbSetUpdateTransferedToParent(false);
+    //  bbSetUpdateTransferedToParent(false);
   }
   //=========================================================================
 
@@ -174,32 +117,22 @@ namespace bbtk
     bbtkDebugMessageInc("process",2,
                        "=> KWBlackBox::bbExecute("<<(int)force<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
-    /*
+  
     // If the output 'Widget' is connected then 
     // we must execute the parent box
     BlackBox::OutputConnectorMapType::const_iterator i 
       = bbGetOutputConnectorMap().find("Widget");
-
+    
     if ( i->second->GetConnectionVector().size() != 0 ) 
       {
-       bbtkDebugMessage("process",3,
-                        "-> Output 'Widget' connected : transfering execution to parent"
-                        <<std::endl);
-       
-       i->second->GetConnectionVector().front() //.lock()
-         ->GetBlackBoxTo()->bbExecute(force);
-
-      }
-    */
-    if (false)
-      {
+       bbtkWarning("Execution called on '"<<bbGetFullName()
+                   <<"' although its Output 'Widget' is connected: "
+                   <<"if the widget is not created yet then it will not be! "
+                   <<"Execute the top level Layout widget to create and "
+                   <<"display the widget.");
       }
-    // else call 'standard' BlackBox execution method
-    else 
-      {
-       AtomicBlackBox::bbExecute(force);
-      }
-    //
+
+    AtomicBlackBox::bbExecute(force);
 
     bbtkDebugMessageDec("process",2,
                        "<= KWBlackBox::bbExecute() ["
@@ -208,108 +141,6 @@ namespace bbtk
   //=========================================================================
 
 
-  //=========================================================================
-  /// Main processing method of the box.
-  IOStatus KWBlackBox::bbBackwardUpdate( Connection::Pointer caller )
-  {
-    /*
-    bbtkDebugMessage("process",3,
-                    "=> KWBlackBox::bbBackwardUpdate("
-                    <<(caller?caller->GetFullName():"0")<<") ["
-                    <<bbGetFullName()<<"]"<<std::endl);
-
-    if ( ! (( bbGetStatus() == MODIFIED ) ||
-           ( bbBoxProcessModeIsAlways() )) )
-      {
-       bbtkDebugMessage("process",3,"Up-to-date : nothing to do"<<std::endl);
-       bbtkDebugMessage("process",3,
-                        "<= KWBlackBox::bbBackwardUpdate("
-                        <<(caller?caller->GetFullName():"0")<<") ["
-                        <<bbGetFullName()<<"]"<<std::endl);
-       return bbGetStatus();
-      }
-    */
-    // If the caller's box to is not the box to connected to the 
-    // output 'Widget'
-    /*
-    BlackBox::OutputConnectorMapType::const_iterator i 
-      = bbGetOutputConnectorMap().find("Widget") ;
-    if ( i->second->GetConnectionVector().size() != 0 )
-      
-      {
-       BlackBox::Pointer to = 
-         i->second->GetConnectionVector()[0]->GetBlackBoxTo();
-               
-       if (caller) 
-         {
-           bbtkDebugMessage("process",3,
-                            "-> Output 'Widget' connected to '"
-                            <<to->bbGetFullName()<<"' - caller->to = '"
-                            <<caller->GetBlackBoxTo()->bbGetFullName()
-                            <<"'"
-                            <<std::endl);
-         }
-       else
-         {
-           bbtkDebugMessage("process",3,
-                            "-> Output 'Widget' connected to '"
-                            <<to->bbGetFullName()<<"'"
-                            <<std::endl);
-         }
-       if ((caller==0) ||
-           ( (caller!=0) && 
-             (caller->GetBlackBoxTo() != to)&&
-             (!bbGetUpdateTransferedToParent())&&
-             (!to->bbGetExecuting()) 
-             )
-           )
-         {
-           bbtkDebugMessage("process",3,
-                            "   ... Transfering update order to parent"
-                            <<std::endl);
-           
-           bbSetUpdateTransferedToParent(true);
-           i->second->GetConnectionVector().front() //.lock()
-             ->GetBlackBoxTo()->bbExecute(false);
-         }
-       else
-         {
-           bbSetUpdateTransferedToParent(false);
-           bbtkDebugMessage("process",3,
-                            "   ... No need to transfer to parent"
-                            <<std::endl);
-         }
-      
-         }
-    */
-    /*    
-
-    // If the caller is not the connection to the output widget
-    // and the output 'Widget' is connected then 
-    // we must execute the parent box 
-    // but only one time 
-    // (this is the role of the flag UpdateTransferedToParent)
-    if ( (caller==0) ||
-        ((caller!=0)&&(caller->GetBlackBoxFromOutput()!="Widget"))
-        )
-      {
-      }
-    */
-    // call 'standard' BlackBox execution method
-    //if (!bbGetUpdateTransferedToParent()) 
-      { 
-         return AtomicBlackBox::bbBackwardUpdate(caller);
-      }
-      /*
-    bbtkDebugMessageDec("process",3,
-                       "<= KWBlackBox::bbBackwardUpdate() ["
-                       <<bbGetFullName()<<"]"<<std::endl);
-      */
-   return bbGetStatus();
-     
-
-  }
-
   //=========================================================================
   void KWBlackBox::bbProcess()
   { 
@@ -415,58 +246,8 @@ namespace bbtk
   }
   //=========================================================================
   
-  /*
-  //=========================================================================
-  void KWBlackBox::bbPlaceWidget()
-  {
-    vtkKWFrame* parent = (vtkKWFrame*)(bbGetOutputWidget()->GetParent());
-    bbGetOutputWidget->GetApplication()->Script("place %s -x 0 -y 0 -width %s -height %s",
-                                               bbGetOutputWidget()->GetWidgetName(),
-                                               parent->GetWidth(),
-                                               parent->GetHeight());
-  }
-  //=========================================================================
-  */
 
-  /*
-  // LG 24/11/08 : New widget pipeline
-  void KWBlackBox::bbCreateWidgetAndEventHandler(vtkKWWidget* parent)
-  {
-    if (bbGetOutputWidget()==0)
-      {
-       this->bbUserCreateWidget(parent);
-      }        
-    
-    // If Event Handler for the widget does not exist or is obsolete : create it 
-    
-      if (bbGetOutputWidget()!=0)
-      {
-       if (bbGetWidgetEventHandler()==0)
-         {
-           bbtkDebugMessage("kw",3,
-                            "-> No widget event handler : creating one"
-                            <<std::endl);
-           new KWBlackBoxWidgetEventHandler(GetThisPointer<KWBlackBox>(),
-                                            bbGetOutputWidget());
-         }
-       else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
-                 ( bbGetOutputWidget() ) )
-         {
-           bbtkDebugMessage("kw",3,
-                            "-> Obsolete widget event handler : re-creating one"
-                            <<std::endl);
-           delete bbGetWidgetEventHandler();
-           new KWBlackBoxWidgetEventHandler(GetThisPointer<KWBlackBox>(),
-                                            bbGetOutputWidget());
-         }
-       // Sets the name of the vtkKWWidget to the input WinTitle
-       bbGetOutputWidget()->SetName(bbtk::std2kw(bbGetInputWinTitle()));
-      }
-   
-  }
-    
-  */
-  
+  //==================================================================
   vtkKWWidget*  KWBlackBox::bbCreateWidgetOfInput(const std::string& in, vtkKWFrame* parent)
   {
     vtkKWWidget* w = 0;
@@ -486,128 +267,7 @@ namespace bbtk
       }
     return w;
   }
-  
-  
-/*
-  //==================================================================
-  /// Specific methods for window creation during pipeline execution
-  /// Shows the window associated to the box 
-  /// (called after bbProcess during bbExecute)
-  void KWBlackBox::bbShowWindow()
-  {
-    bbtkDebugMessageInc("kw",1,"=> KWBlackBox::bbShowWindow() ["
-                       <<bbGetFullName()<<"]"<<std::endl);
-    // If Event Handler for the widget does not exist or is obsolete : create it 
-    if (bbGetOutputWidget()!=0)
-      {
-       if (bbGetWidgetEventHandler()==0)
-         {
-           bbtkDebugMessage("kw",3,
-                            "-> No widget event handler : creating one"
-                            <<std::endl);
-           new KWBlackBoxWidgetEventHandler(GetThisPointer<KWBlackBox>(),
-                                            bbGetOutputWidget());
-         }
-       else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
-                 ( bbGetOutputWidget() ) )
-         {
-           bbtkDebugMessage("kw",3,
-                            "-> Obsolete widget event handler : re-creating one"
-                            <<std::endl);
-           delete bbGetWidgetEventHandler();
-           new KWBlackBoxWidgetEventHandler(GetThisPointer<KWBlackBox>(),
-                                            bbGetOutputWidget());
-         }
-       // Sets the name of the vtkKWWidget to the input WinTitle
-       bbGetOutputWidget()->SetName(bbtk::std2kw(bbGetInputWinTitle()));
-      }
-
-    // If the output 'Widget' is connected then it's gonna 
-    // be captured by its parent window : nothing to do 
-    if ( (*bbGetOutputConnectorMap().find("Widget")).second
-        ->GetConnectionVector().size() != 0 ) 
-      {
-       
-       bbtkDebugMessage("kw",2,
-                        "-> Output 'Widget' connected : nothing to do"
-                        <<std::endl);
-       return;
-      }
-
-
-    Window* show = 0;
-    // If the window already exists : no need creating it
-    if (bbGetWindow()!=0)
-      {
-       bbtkDebugMessage("kw",2,
-                        "-> Window already exists"
-                        <<std::endl);
-       show = bbGetWindow();
-      }
-    // Else if the widget exists : create window 
-    else if (bbGetOutputWidget()!=0) 
-      {
-       bbtkDebugMessage("kw",2,
-                        "-> Widget exists : creating the window"
-                        <<std::endl);
-
-
-       // Input WinDialog set to true : creating a Dialog
-       if (bbGetInputWinDialog()) 
-         {
-           bbtkDebugMessage("kw",2,
-                            "   Input WinDialog set to true : creating a Dialog"
-                            <<std::endl);
-           show = (Window*) new KWBlackBoxDialog( GetThisPointer<KWBlackBox>(),
-                                                 // bbGetKWParent(), 
-                                                                                         // LG 24/11/08 : New widget pipeline
-                                                                                         KW::GetTopWindow(),
-                                                  std2kw( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
-                                                  kwSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
-         }
-       // Input WinDialog set to false : creating a Frame
-       else 
-         {
-           bbtkDebugMessage("process",2,
-                            "   Input WinDialog set to false : creating a Frame"
-                            <<std::endl);
-           show = (Window*) new KWBlackBoxFrame( GetThisPointer<KWBlackBox>(),
-                                                 // bbGetKWParent(), 
-                                                                                        // LG 24/11/08 : New widget pipeline
-                                                                                        KW::GetTopWindow(),
-                                                 std2kw( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
-                                                 kwSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
-         }
-
-      }
-    // No window nor widget : error
-    else
-      {
-       bbtkError("KWBlackBox::bbShowWindow() ["
-                 <<bbGetFullName()
-                 <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
-      }
-    
-    // Show the window
-    if (true) //!show->IsShown())
-      {
-       show->bbShow(); 
-      }
-    else 
-      {
-       bbtkDebugMessage("kw",2,"-> Already shown : nothing to do"<<std::endl);
-      }
-  
-
-    bbtkDebugMessage("kw",2,"<= KWBlackBox::bbShowWindow() ["
-                       <<bbGetFullName()<<"]"<<std::endl);
-
-  }
   //==================================================================
-*/
-
 
 
   //==================================================================
@@ -654,12 +314,6 @@ namespace bbtk
   //==================================================================
 
 
-  //==================================================================
-       // LG 24/11/08 : New widget pipeline
-       //  vtkKWWidget* KWBlackBox::bbGetKWParent() { return KW::GetTopWindow(); }
-  //==================================================================
-  
-  
   //==================================================================
   bool KWBlackBox::bbIsShown()
   {
index 754a7dd5fe2ef2d89e89537112f6248539e157ce..f10a989050a29dcbc2596ee16eeb18481730e24a 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkKWBlackBox.h,v $
   Language:  C++
-  Date:      $Date: 2008/12/02 13:37:54 $
-  Version:   $Revision: 1.3 $
+  Date:      $Date: 2008/12/08 12:54:26 $
+  Version:   $Revision: 1.4 $
 ========================================================================*/
 
 
@@ -162,7 +162,7 @@ namespace bbtk
 
     //==================================================================
     /// Main processing method of the box.
-    virtual IOStatus bbBackwardUpdate( Connection::Pointer caller );
+    //    virtual void bbBackwardUpdate( Connection::Pointer caller );
     //==================================================================
 
 
@@ -210,7 +210,7 @@ namespace bbtk
 
   protected :
 
-
+    /*
     /// For Forward update mechanism when execution is called 
     /// on a contained window
     /// Is set to true before transfering update to parent 
@@ -220,7 +220,7 @@ namespace bbtk
     bool bbGetUpdateTransferedToParent() const { return bbmUpdateTransferedToParent; }
     void bbSetUpdateTransferedToParent(bool b) 
     { bbmUpdateTransferedToParent = b; }
-
+    */
   };
   //=================================================================
  
index d3333d947ac1eb80209fbd176d5fde157baa957e..eae9e3b41d3d5bcc2a9154d009bd048aa8c0931b 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkMessageManager.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/11/29 21:41:34 $
-  Version:   $Revision: 1.13 $
+  Date:      $Date: 2008/12/08 12:54:27 $
+  Version:   $Revision: 1.14 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -106,9 +106,9 @@ namespace bbtk
     mMessageLevel[key] = 0;
     mMessageHelp[key] = "Connections related messages";
     if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
-    key = "modified";
+    key = "change";
     mMessageLevel[key] = 0;
-    mMessageHelp[key] = "Modified related messages";
+    mMessageHelp[key] = "Box i/o changes related messages";
     if (mMaxMessageLength<key.length()) mMaxMessageLength = key.length();
    }
 
index e99469cad07d2576e08d2906ed2a2947b86512e3..4ccfe67a2b8661f5416806620cb545ef5aad00fd 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkWxBlackBox.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/12/03 09:38:02 $
-  Version:   $Revision: 1.32 $
+  Date:      $Date: 2008/12/08 12:54:27 $
+  Version:   $Revision: 1.33 $
 =========================================================================*/
 
 /* ---------------------------------------------------------------------
@@ -39,6 +39,8 @@
  */
  
 #include "bbtkWxBlackBox.h"
+#include "bbtkBlackBoxOutputConnector.h"
+
 //#include "bbtkWxContainerBlackBox.h"
 #include <wx/dialog.h>
 
@@ -327,7 +329,8 @@ namespace bbtk
     bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::OnWindowDestroy() ["
                     <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
     mBox.lock()->bbSetOutputWidget(0);
-    mBox.lock()->bbSetModifiedStatus();
+    // LGSIGNAL
+    //    mBox.lock()->bbSetModifiedStatus();
   }
   //=========================================================================
 
@@ -414,7 +417,7 @@ namespace bbtk
     bbSetOutputWidget(0);
 
     bbSetWidgetEventHandler(0);
-    bbSetUpdateTransferedToParent(false);
+    //    bbSetUpdateTransferedToParent(false);
   }
   //=========================================================================
 
@@ -422,279 +425,165 @@ namespace bbtk
   /// Main processing method of the box.
   void WxBlackBox::bbExecute(bool force)
   {
-    /*
+    
     bbtkDebugMessageInc("process",2,
                        "=> WxBlackBox::bbExecute("<<(int)force<<") ["
                        <<bbGetFullName()<<"]"<<std::endl);
-    */
-    /*
+    
+    
     // If the output 'Widget' is connected then 
     // we must execute the parent box
     BlackBox::OutputConnectorMapType::const_iterator i 
       = bbGetOutputConnectorMap().find("Widget");
-
+    
     if ( i->second->GetConnectionVector().size() != 0 ) 
       {
-       bbtkDebugMessage("process",3,
-                        "-> Output 'Widget' connected : transfering execution to parent"
-                        <<std::endl);
-       
-       i->second->GetConnectionVector().front() //.lock()
-         ->GetBlackBoxTo()->bbExecute(force);
-
-      }
-    */
-    /*
-    if (false)
-      {
-      }
-    // else call 'standard' BlackBox execution method
-    else 
-      {
-    */
-       return AtomicBlackBox::bbExecute(force);
-       /*
+       bbtkWarning("Execution called on '"<<bbGetFullName()
+                   <<"' although its Output 'Widget' is connected: "
+                   <<"if the widget is not created yet then it will not be! "
+                   <<"Execute the top level Layout widget to create and "
+                   <<"display the widget.");
       }
-    //
+
+    AtomicBlackBox::bbExecute(force);
 
     bbtkDebugMessageDec("process",2,
                        "<= WxBlackBox::bbExecute() ["
                        <<bbGetFullName()<<"]"<<std::endl);
-       */
   }
   //=========================================================================
 
 
   //=========================================================================
-  /// Main processing method of the box.
-  IOStatus WxBlackBox::bbBackwardUpdate( Connection::Pointer caller )
-  {
-    bbtkDebugMessage("process",3,
-                    "=> WxBlackBox::bbBackwardUpdate("
-                    <<(caller?caller->GetFullName():"0")<<") ["
-                    <<bbGetFullName()<<"]"<<std::endl);
-
-    if ( ! (( bbGetStatus() == MODIFIED ) ||
-           ( bbBoxProcessModeIsAlways() )) )
-      {
-       bbtkDebugMessage("process",3,"Up-to-date : nothing to do"<<std::endl);
-       bbtkDebugMessage("process",3,
-                        "<= WxBlackBox::bbBackwardUpdate("
-                        <<(caller?caller->GetFullName():"0")<<") ["
-                        <<bbGetFullName()<<"]"<<std::endl);
-       return bbGetStatus();
-      }
-    // If the caller's box to is not the box to connected to the 
-    // output 'Widget'
-    /*
-    BlackBox::OutputConnectorMapType::const_iterator i 
-      = bbGetOutputConnectorMap().find("Widget") ;
-    if ( i->second->GetConnectionVector().size() != 0 )
-      
+  void WxBlackBox::bbProcess()
+  { 
+/*
+         if (bbGetOutputWidget()==0) this->bbUserCreateWidget();
+         this->bbUserProcess(); 
+         bbShowWindow();
+         //    this->bbUserOnShow();
+         */
+    // LG 22/11/08 : new widget pipeline
+    // If output widget not connected : 
+    if ( (*bbGetOutputConnectorMap().find("Widget")).second
+        ->GetConnectionVector().size() == 0 ) 
       {
-       BlackBox::Pointer to = 
-         i->second->GetConnectionVector()[0]->GetBlackBoxTo();
-               
-       if (caller) 
+       Window* show = 0;
+       // If the window already exists : no need creating it
+       if (bbGetWindow()!=0)
          {
-           bbtkDebugMessage("process",3,
-                            "-> Output 'Widget' connected to '"
-                            <<to->bbGetFullName()<<"' - caller->to = '"
-                            <<caller->GetBlackBoxTo()->bbGetFullName()
-                            <<"'"
+           bbtkDebugMessage("wx",2,
+                            "-> Window already exists"
                             <<std::endl);
+           show = bbGetWindow();
          }
-       else
+       // Else create window 
+       else 
          {
-           bbtkDebugMessage("process",3,
-                            "-> Output 'Widget' connected to '"
-                            <<to->bbGetFullName()<<"'"
+           bbtkDebugMessage("wx",2,
+                            "-> Creating the window"
                             <<std::endl);
+           
+           
+           // Input WinDialog set to true : creating a Dialog
+           if (bbGetInputWinDialog()) 
+             {
+               bbtkDebugMessage("wx",2,
+                                "   Input WinDialog set to true : creating a Dialog"
+                                <<std::endl);
+               show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
+                                                      // bbGetWxParent(), 
+                                                      // LG 24/11/08 : New widget pipeline
+                                                      Wx::GetTopWindow(),
+                                                      std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
+                                                      wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
+             }
+           // Input WinDialog set to false : creating a Frame
+           else 
+             {
+               bbtkDebugMessage("process",2,
+                                "   Input WinDialog set to false : creating a Frame"
+                                <<std::endl);
+               show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
+                                                     // bbGetWxParent(), 
+                                                     // LG 24/11/08 : New widget pipeline
+                                                     Wx::GetTopWindow(),
+                                                     std2wx( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
+                                                     wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
+             }
+           
          }
-       if ((caller==0) ||
-           ( (caller!=0) && 
-             (caller->GetBlackBoxTo() != to)&&
-             (!bbGetUpdateTransferedToParent())&&
-             (!to->bbGetExecuting()) 
-             )
-           )
+       
+       // Show the window
+       show->bbShow(); 
+       
+       
+      }                  
+    this->bbUserProcess(); 
+    
+  }
+  //=========================================================================
+       
+       
+  // LG 24/11/08 : New widget pipeline
+  void WxBlackBox::bbCreateWidgetAndEventHandler(wxWindow* parent)
+  {
+    if (bbGetOutputWidget()==0)
+      {
+       this->bbUserCreateWidget(parent);
+      }                
+    // If Event Handler for the widget does not exist or is obsolete : create it 
+    if (bbGetOutputWidget()!=0)
+      {
+       if (bbGetWidgetEventHandler()==0)
          {
-           bbtkDebugMessage("process",3,
-                            "   ... Transfering update order to parent"
+           bbtkDebugMessage("wx",3,
+                            "-> No widget event handler : creating one"
                             <<std::endl);
-           
-           bbSetUpdateTransferedToParent(true);
-           i->second->GetConnectionVector().front() //.lock()
-             ->GetBlackBoxTo()->bbExecute(false);
+           new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
+                                            bbGetOutputWidget());
          }
-       else
+       else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
+                 ( bbGetOutputWidget() ) )
          {
-           bbSetUpdateTransferedToParent(false);
-           bbtkDebugMessage("process",3,
-                            "   ... No need to transfer to parent"
+           bbtkDebugMessage("wx",3,
+                            "-> Obsolete widget event handler : re-creating one"
                             <<std::endl);
+           delete bbGetWidgetEventHandler();
+           new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
+                                            bbGetOutputWidget());
          }
-      }
-    */
-    /*    
-
-    // If the caller is not the connection to the output widget
-    // and the output 'Widget' is connected then 
-    // we must execute the parent box 
-    // but only one time 
-    // (this is the role of the flag UpdateTransferedToParent)
-    if ( (caller==0) ||
-        ((caller!=0)&&(caller->GetBlackBoxFromOutput()!="Widget"))
-        )
-      {
-      }
-    */
-    // call 'standard' BlackBox execution method
-    if (!bbGetUpdateTransferedToParent()) 
-      { 
-         AtomicBlackBox::bbBackwardUpdate(caller);
+       // Sets the name of the wxWindow to the input WinTitle
+       bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
       }
     
-    bbtkDebugMessageDec("process",3,
-                       "<= WxBlackBox::bbBackwardUpdate() ["
-                       <<bbGetFullName()<<"]"<<std::endl);
     
-   return bbGetStatus();
-     
-
   }
-
-  //=========================================================================
-  void WxBlackBox::bbProcess()
-  { 
-/*
-         if (bbGetOutputWidget()==0) this->bbUserCreateWidget();
-    this->bbUserProcess(); 
-    bbShowWindow();
-    //    this->bbUserOnShow();
-*/
-         // LG 22/11/08 : new widget pipeline
-         // If output widget not connected : 
-         if ( (*bbGetOutputConnectorMap().find("Widget")).second
-                 ->GetConnectionVector().size() == 0 ) 
+  
+  
+  
+  wxWindow*  WxBlackBox::bbCreateWidgetOfInput(const std::string& in, wxWindow* parent)
+  {
+    wxWindow* w = 0;
+    // If input is connected 
+    BlackBoxInputConnector* c = bbGetInputConnectorMap().find(in)->second ;
+    if ( c->IsConnected() )                    
       {
-                 Window* show = 0;
-                 // If the window already exists : no need creating it
-                 if (bbGetWindow()!=0)
-                 {
-                         bbtkDebugMessage("wx",2,
-                                                          "-> Window already exists"
-                                                          <<std::endl);
-                         show = bbGetWindow();
-                 }
-                 // Else create window 
-                 else 
-                 {
-                         bbtkDebugMessage("wx",2,
-                                                          "-> Creating the window"
-                                                          <<std::endl);
-                         
-                         
-                         // Input WinDialog set to true : creating a Dialog
-                         if (bbGetInputWinDialog()) 
-                         {
-                                 bbtkDebugMessage("wx",2,
-                                                                  "   Input WinDialog set to true : creating a Dialog"
-                                                                  <<std::endl);
-                                 show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
-                                                                                                               // bbGetWxParent(), 
-                                                                                                               // LG 24/11/08 : New widget pipeline
-                                                                                                               Wx::GetTopWindow(),
-                                                                                                               std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
-                                                                                                               wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
-                         }
-                         // Input WinDialog set to false : creating a Frame
-                         else 
-                         {
-                                 bbtkDebugMessage("process",2,
-                                                                  "   Input WinDialog set to false : creating a Frame"
-                                                                  <<std::endl);
-                                 show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
-                                                                                                          // bbGetWxParent(), 
-                                                                                                          // LG 24/11/08 : New widget pipeline
-                                                                                                          Wx::GetTopWindow(),
-                                                                                                          std2wx( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
-                                                                                                          wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
-                         }
-                                                 
-                 }
-               
-                 // Show the window
-                 show->bbShow(); 
-                 
-                 
-         }               
-         this->bbUserProcess(); 
-         
+       // Get black box from 
+       BlackBox::Pointer from = 
+         c->GetConnection()->GetBlackBoxFrom();
+       // Cast it into a WxBlackBox
+       WxBlackBox::Pointer wfrom = boost::dynamic_pointer_cast<WxBlackBox>(from);
+       // Call bbCreateWidgetAndEventHandler
+       wfrom->bbCreateWidgetAndEventHandler(parent);
+       // Get the widget created
+       w = wfrom->bbGetOutputWidget();
+      }
+    return w;
   }
-  //=========================================================================
-       
-       
-       // LG 24/11/08 : New widget pipeline
-       void WxBlackBox::bbCreateWidgetAndEventHandler(wxWindow* parent)
-       {
-               if (bbGetOutputWidget()==0)
-               {
-                       this->bbUserCreateWidget(parent);
-               }               
-               // If Event Handler for the widget does not exist or is obsolete : create it 
-               if (bbGetOutputWidget()!=0)
-               {
-                       if (bbGetWidgetEventHandler()==0)
-                       {
-                               bbtkDebugMessage("wx",3,
-                                                                "-> No widget event handler : creating one"
-                                                                <<std::endl);
-                               new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
-                                                                                                bbGetOutputWidget());
-                       }
-                       else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
-                                        ( bbGetOutputWidget() ) )
-                       {
-                               bbtkDebugMessage("wx",3,
-                                                                "-> Obsolete widget event handler : re-creating one"
-                                                                <<std::endl);
-                               delete bbGetWidgetEventHandler();
-                               new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
-                                                                                                bbGetOutputWidget());
-                       }
-                       // Sets the name of the wxWindow to the input WinTitle
-                       bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
-               }
-               
-               
-       }
-
-
-       
-       wxWindow*  WxBlackBox::bbCreateWidgetOfInput(const std::string& in, wxWindow* parent)
-       {
-               wxWindow* w = 0;
-               // If input is connected 
-               BlackBoxInputConnector* c = bbGetInputConnectorMap().find(in)->second ;
-               if ( c->IsConnected() )                 
-               {
-                       // Get black box from 
-                       BlackBox::Pointer from = 
-                       c->GetConnection()->GetBlackBoxFrom();
-                       // Cast it into a WxBlackBox
-                       WxBlackBox::Pointer wfrom = boost::dynamic_pointer_cast<WxBlackBox>(from);
-                       // Call bbCreateWidgetAndEventHandler
-                       wfrom->bbCreateWidgetAndEventHandler(parent);
-                       // Get the widget created
-                       w = wfrom->bbGetOutputWidget();
-               }
-               return w;
-       }
-
-       /*
+  
+  /*
   //==================================================================
   /// Specific methods for window creation during pipeline execution
   /// Shows the window associated to the box 
index e2857e0d47c57d0f87ce4d0b548272b77bbb138a..2d9084c43f9102696717954adeb434957ea66d5e 100644 (file)
@@ -2,8 +2,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkWxBlackBox.h,v $
   Language:  C++
-  Date:      $Date: 2008/11/25 11:17:13 $
-  Version:   $Revision: 1.21 $
+  Date:      $Date: 2008/12/08 12:54:27 $
+  Version:   $Revision: 1.22 $
 ========================================================================*/
 
 
@@ -125,9 +125,9 @@ namespace bbtk
     virtual void bbUserOnHide() {}
     //==================================================================    
 
-         // LG 24/11/08 : New widget pipeline
-         void bbCreateWidgetAndEventHandler(wxWindow* parent); 
 
+   // LG 24/11/08 : New widget pipeline
+    void bbCreateWidgetAndEventHandler(wxWindow* parent); 
          
   protected:
     
@@ -144,30 +144,32 @@ namespace bbtk
     //==================================================================    
     /// User callback for creating the widget associated to the box
     /// ** Must be defined **
-         // LG 24/11/08 : New widget pipeline
-         virtual void bbUserCreateWidget(wxWindow* parent) 
+    // LG 24/11/08 : New widget pipeline
+    virtual void bbUserCreateWidget(wxWindow* parent) 
     {
       bbtkError(bbGetTypeName()<<" is a WxBlackBox whose bbUserCreateWidget methods is not overloaded : is it a feature or a bug ?!?");
     }
     //==================================================================    
 
 
-         wxWindow* bbCreateWidgetOfInput(const std::string& in, wxWindow* parent);
+    //==================================================================    
+    // For layout widgets : creates and returns the widget 
+    // of the box connected to input in
+    wxWindow* bbCreateWidgetOfInput(const std::string& in, wxWindow* parent);
+    //==================================================================    
 
 
     //==================================================================
     /// Main processing method of the box.
-    virtual IOStatus bbBackwardUpdate( Connection::Pointer caller );
+    //  No more overloaded
+    //  virtual void bbBackwardUpdate( Connection::Pointer caller );
     //==================================================================
 
-
 
     //==================================================================
-    /// Overloaded processing method for WxBlackBoxes :
-    /// 1) if the widget is null then 
-    ///    calls the user defined widget creation method : bbUserCreateWidget()
-    /// 2) calls the user defined processing method : bbUserProcess()
-    /// 3) displays the window : bbShowWindow();
+    /// Overloaded processing method for WxBlackBoxes which handles 
+    /// the window creation if needed
     virtual void bbProcess();
     //==================================================================
 
@@ -215,12 +217,13 @@ namespace bbtk
     /// on a contained window
     /// Is set to true before transfering update to parent 
     /// in order to not re-transfer a second time...
+    /*
     bool bbmUpdateTransferedToParent;
 
     bool bbGetUpdateTransferedToParent() const { return bbmUpdateTransferedToParent; }
     void bbSetUpdateTransferedToParent(bool b) 
     { bbmUpdateTransferedToParent = b; }
-
+    */
   };
   //=================================================================
  
index 929147e12b02085c35ee26a838b39b21adee96ed..5d43509e8c0d3bb3ac1c123c78337c4d3cbe601b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbwxvtkViewer2D.cxx,v $
   Language:  C++
-  Date:      $Date: 2008/12/03 13:35:35 $
-  Version:   $Revision: 1.27 $
+  Date:      $Date: 2008/12/08 12:56:03 $
+  Version:   $Revision: 1.28 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -53,7 +53,7 @@ namespace bbwxvtk
     wxvtkrenderwindowinteractor = new wxVTKRenderWindowInteractor(panel,-1);
     wxvtkrenderwindowinteractor->UseCaptureMouseOn();  
 
-    imageViewer        = vtkImageViewer2::New();
+    imageViewer        = wxvtkImageViewer2::New();
     imageViewer->SetSlice( 1 );
     imageViewer->SetupInteractor ( wxvtkrenderwindowinteractor );
     
@@ -130,18 +130,37 @@ namespace bbwxvtk
   {
     //    std::cout << "Viewer2DWidget::UpdateView() "<<mBox->bbGetFullName() << std::endl;
     //   std::cout << "slice="<<mBox->bbGetInputSlice()<<std::endl;
+    
+    std::cout << "--- Testing status of input connection 'In'" << std::endl;
+    bbtk::BlackBoxInputConnector* c =  mBox->bbGetInputConnectorMap().find("In")->second ;
+    if (c->GetStatus()==bbtk::MODIFIED) 
+      {
+       std::cout << "===> MODIFIED"<<std::endl;
+      }
+    else if (c->GetStatus()==bbtk::UPTODATE) 
+      {
+       std::cout << "===> UPTODATE"<<std::endl;
+      }
+
+
 
 
     if ( ( mBox->bbGetInputIn() == NULL ) &&
         ( backImageData != mDefaultImage ) )
       {
+       // 
+       std::cout << "** Viewer2DWidget::UpdateView() : NULL Input (reset)"
+                 <<std::endl;
        backImageData = mDefaultImage;
        mUpdateCamera = true;
+
       }
     else if ( ( mBox->bbGetInputIn() != NULL ) && 
              //      (true) ) //
              (backImageData != mBox->bbGetInputIn()) ) 
       {
+       std::cout << "** Viewer2DWidget::UpdateView() : Input changed"
+                 <<std::endl;
        backImageData = mBox->bbGetInputIn();
        backImageData->Update();
        imageViewer->SetInput( backImageData );
@@ -150,6 +169,8 @@ namespace bbwxvtk
 
     if (mUpdateCamera)
       {
+       std::cout << "** Viewer2DWidget::UpdateView() : Update Camera"
+                 <<std::endl;
        int x1,x2,y1,y2,z1,z2;
        double spx,spy,spz;
        backImageData->GetSpacing(spx,spy,spz);
@@ -238,10 +259,10 @@ namespace bbwxvtk
                bbtkMessage("Output", 2, "Viewer2D : Orientation was not 0< <2 (shouldn't arrive here!"<<std::endl);
                z = ext[5]; // Why not?
            }
-
+           wxvtkrenderwindowinteractor->Refresh();
+           wxvtkrenderwindowinteractor->Render();
            bbtkDebugMessage("Output",3,"Viewer2D : slice = "<<z<<std::endl);
            imageViewer->SetSliceOrientation (orientation);
-           wxvtkrenderwindowinteractor->Render();
            imageViewer->SetSlice( z );
 
     } 
index c49437539f49ddabe3a39fbbddc152ca54e8fa08..5019b96d54f4d364fa818a3b81c974b66202a797 100644 (file)
@@ -3,8 +3,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbwxvtkViewer2D.h,v $
   Language:  C++
-  Date:      $Date: 2008/12/03 13:35:35 $
-  Version:   $Revision: 1.11 $
+  Date:      $Date: 2008/12/08 12:56:17 $
+  Version:   $Revision: 1.12 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -38,7 +38,7 @@
 #define __bbwxvtkViewer2D_h__
 
 #include "vtkImageData.h"
-#include "vtkImageViewer2.h"
+#include "wxvtkImageViewer2.h"
 #include "vtkImplicitPlaneWidget.h"
 
 #include "bbtkWxBlackBox.h"
@@ -61,7 +61,7 @@ namespace bbwxvtk
     vtkRenderer                *GetRenderer();
   private:
     Viewer2D                    *mBox;
-    vtkImageViewer2            *imageViewer;
+    wxvtkImageViewer2          *imageViewer;
     vtkImageData               *backImageData;
     vtkImageData               *mDefaultImage;
     wxVTKRenderWindowInteractor *wxvtkrenderwindowinteractor;