]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkBlackBox.h
#3005 BBTK Feature New Normal - TypeName in message system BlackBox
[bbtk.git] / kernel / src / bbtkBlackBox.h
index ba86ed664290cfeceb395a7e45c974dd2ccb588b..db02118273aaa83c2f12a3e7f912c656dca50d1e 100644 (file)
+/*
+ # ---------------------------------------------------------------------
+ #
+ # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
+ #                        pour la SantÈ)
+ # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
+ # Previous Authors : Laurent Guigues, Jean-Pierre Roux
+ # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
+ #
+ #  This software is governed by the CeCILL-B license under French law and
+ #  abiding by the rules of distribution of free software. You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL-B
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ #  or in the file LICENSE.txt.
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL-B license and that you accept its terms.
+ # ------------------------------------------------------------------------ */
+
+
 /*=========================================================================
-                                                                                
   Program:   bbtk
   Module:    $RCSfile: bbtkBlackBox.h,v $
   Language:  C++
-  Date:      $Date: 2008/05/15 08:02:36 $
-  Version:   $Revision: 1.10 $
-                                                                                
-  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
-  l'Image). All rights reserved. See doc/license.txt or
-  http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
-                                                                                
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-                                                                                
+  Date:      $Date: 2012/11/16 08:49:01 $
+  Version:   $Revision: 1.34 $
 =========================================================================*/
 
 
+
 /**
- *  \file 
- *  \brief Class bbtk::BlackBox : abstract black-box interface. 
+ *  \file
+ *  \brief Class bbtk::BlackBox : abstract black-box interface.
  */
 
 /**
  * \class bbtk::BlackBox
- * \brief Abstract black-box interface 
+ * \brief Abstract black-box interface
  */
+
 #ifndef __bbtkBlackBox_h__
 #define __bbtkBlackBox_h__
 
 #include "bbtkSystem.h"
+#include "bbtkMessageManager.h"
 #include "bbtkBlackBoxDescriptor.h"
 #include "bbtkBlackBoxInputConnector.h"
-#include "bbtkBlackBoxOutputConnector.h"
+//#include "bbtkBlackBoxOutputConnector.h"
 #include <set>
 
+// Signal/slot mechanism for output change events
+#include <boost/signals2/signal.hpp>
+#include <boost/bind.hpp>
+
+
+#define bbtkBlackBoxMessage(key,level,mess) \
+  bbtkMessage(key,level,"["<<bbGetTypeName()<<":"<<bbGetName()<<"] "<<mess)
+#define bbtkBlackBoxDebugMessage(key,level,mess)       \
+  bbtkDebugMessage(key,level,"["<<bbGetTypeName()<<":"<<bbGetName()<<"] "<<mess)
+
 namespace bbtk
 {
 
-  
   struct Void { Void(int = 0) {} };
-  
+
   class Factory;
   class Connection;
+  class BlackBoxOutputConnector;
 
   class BBTK_EXPORT BlackBox : public Object
   {
     BBTK_ABSTRACT_OBJECT_INTERFACE(BlackBox);
-  public: 
+
+
+  public:
+
     //==================================================================
-    // INTERFACE
+    // Types
     //==================================================================
+    typedef boost::signals2::trackable OutputChangeObserverType;
+    typedef boost::signals2::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*> 
+    typedef std::map<std::string, BlackBoxOutputConnector*>
     OutputConnectorMapType;
     /// The type of map of input connector pointers
-    typedef std::map<std::string, BlackBoxInputConnector*> 
+    typedef std::map<std::string, BlackBoxInputConnector*>
     InputConnectorMapType;
+    //==================================================================
 
-    /// Returns the pointer on the descriptor of the box
-    virtual BlackBoxDescriptor::Pointer bbGetDescriptor() const = 0;
 
+    //==================================================================
+    /// @name Pipeline processing methods
+    ///  Methods which participate to pipeline processing.
+    //@{
+    /// Main processing method of the box.
+    virtual void bbExecute(bool force = false);
+    //@}
+    //==================================================================
+
+
+
+
+
+    //==================================================================
     /// Returns a pointer on a clone of the box with name <name>
     virtual BlackBox::Pointer bbClone(const std::string& name) = 0;
+    //==================================================================
 
-    /// User overloadable destruction method of a black box
-    virtual void bbUserDelete();
+
+   //==================================================================
+    /// @name General accessors
+    ///  Methods which give access to general informations on the box
+    //@{
+
+    /// Returns the pointer on the descriptor of the box
+    virtual BlackBoxDescriptor::Pointer bbGetDescriptor() const = 0;
 
     /// Returns the Name of the Type of the BlackBox
-    const std::string& bbGetTypeName() const 
+    const std::string& bbGetTypeName() const
       { return bbGetDescriptor()->GetTypeName(); }
-    
+
+
     /// Returns the name of the BlackBox (instance)
     const std::string& bbGetName() const { return bbmName; }
 
@@ -82,286 +140,373 @@ namespace bbtk
 
     /// Returns the name with the name of the parent prepended if any
     virtual std::string bbGetNameWithParent() const;
-    
+
     /// Returns the parent of the BlackBox, i.e the BlackBox that contains it (0 if none)
     BlackBox::Pointer bbGetParent() const { return bbmParent.lock(); }
 
+    //@}
+    //==================================================================
 
-    /// 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
-    virtual void bbSetModifiedStatus(BlackBoxInputConnector* c = 0);
-    /// Signals that the BlackBox outputs have been modified 
-    /// without marking the box as MODIFIED because its output state is ok. 
-    /// This method should be used by widgets in response 
-    /// to user interaction when **ALL** outputs have been modified
-    /// (after the outputs has been updated !)
-    virtual void bbSignalOutputModification(bool reaction = true);
-    ///  Signals that the BlackBox output "output_name" have been modified 
-    /// without marking the box as MODIFIED because its output state is ok. 
-    /// This method should be used by widgets in response to user interaction 
-    /// only when **ONE** output has been modified
-    /// (after the output has been updated !)
-    virtual void bbSignalOutputModification( const std::string& output_name,
-bool reaction = true);
-    ///  Signals that the BlackBox vector of outputs "output_name" 
-    ///  have been modified 
-    /// without marking the box as MODIFIED because its output state is ok. 
-    /// This method should be used by widgets in response to user interaction 
-    /// When more than one output has been changed but not all
-    /// (after the outputs have been updated of course!)
-    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; }
 
+    //==================================================================
+    /// @name Inputs/Outputs related methods
+    ///  Methods related to the box inputs and outputs
+    //@{
 
     /// Returns true iff the BlackBox has an input of name label
     virtual bool bbHasInput(const std::string& label) const;
-    /// Returns true iff the BlackBox has an output of name label
-    virtual bool bbHasOutput(const std::string& label) const;
-
     ///  Gets the input type of a given label
     virtual TypeInfo bbGetInputType( const std::string &label ) const;
-    ///  Gets the output type of a given label
-    virtual TypeInfo bbGetOutputType( const std::string &label ) const;
-
+    /// Gets the status of the input called <name>
+    IOStatus bbGetInputStatus( const std::string &name ) const
+    { return mInputConnectorMap.find(name)->second->GetStatus(); }
     ///  Gets the data of the input called <name>
     virtual Data bbGetInput( const std::string &name )  = 0;
+    ///  Gets the data of the input called <name> as a string using an Adaptor if possible (else returns empty string)
+    std::string bbGetInputAsString( const std::string &input);
+
+
+   /// Sets the data of the input called <name>.
+    /// If update_time is false then does not update ChangeTime of input
+    virtual void bbSetInput( const std::string &name, Data data,
+                            bool update_time = true ) = 0;
+    /// [SYSTEM]: Sets the data of the input called <name> which **MUST* be a pointer
+    virtual void bbBruteForceSetInputPointer( const std::string &name,
+                                             void* data,
+                                             bool update_time = true) =0;
+
+
+    /// Returns true iff the BlackBox has an output of name label
+    virtual bool bbHasOutput(const std::string& label) const;
+    ///  Gets the output type of a given label
+    virtual TypeInfo bbGetOutputType( const std::string &label ) const;
     ///  Gets the data of the output called <name>
     virtual Data bbGetOutput( const std::string &name ) = 0;
+    ///  Gets the data of the output called <name> as a string using an Adaptor if possible (else returns empty string)
+    std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
 
-    /// Sets the data of the input called <name>.
-    /// If setModified is false then does not call bbSetModifiedStatus()
-    virtual void bbSetInput( const std::string &name, Data data,
-                            bool setModified = true ) = 0;
-    virtual void bbBruteForceSetInputPointer( const std::string &name, 
-                                             void* data, 
-                                             bool setModified = true) =0;
     ///  Sets the data of the output called <name>
     virtual void bbSetOutput( const std::string &name, Data data) = 0;
 
 
     ///  Returns the input connectors map
-    InputConnectorMapType&  bbGetInputConnectorMap() 
+    InputConnectorMapType&  bbGetInputConnectorMap()
     { return mInputConnectorMap; }
+    ///  Returns the input connectors map (const)
+    const InputConnectorMapType&  bbGetInputConnectorMap() const
+    { return mInputConnectorMap; }
+   ///  Returns the input connector
+    BlackBoxInputConnector&  bbGetInputConnector(const std::string& n)
+    { return *(mInputConnectorMap.find(n)->second); }
+    ///  Returns the input connector (const)
+    const BlackBoxInputConnector&  bbGetInputConnector(const std::string& n) const
+    { return *(mInputConnectorMap.find(n)->second); }
+
+
     ///  Returns the output connectors map
-    OutputConnectorMapType& bbGetOutputConnectorMap() 
+    OutputConnectorMapType& bbGetOutputConnectorMap()
     { return mOutputConnectorMap; }
-    ///  Returns the input connectors map (const)
-    const InputConnectorMapType&  bbGetInputConnectorMap() const 
-    { return mInputConnectorMap; } 
     ///  Returns the output connectors map (const)
-    const OutputConnectorMapType& bbGetOutputConnectorMap() const 
-    { return mOutputConnectorMap; }      
+    const OutputConnectorMapType& bbGetOutputConnectorMap() const
+    { return mOutputConnectorMap; }
+    ///  Returns the output connector
+    BlackBoxOutputConnector& bbGetOutputConnector(const std::string& n)
+    { return *(mOutputConnectorMap.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 
+    /// Prints the Help on the BlackBox type
     virtual void bbGetHelp(bool full=true) const;
 
 
+
+    //==================================================================
+    /// @name Output signals / observers related methods
+    ///  Methods related to signals emitted by outputs and the
+    //@{
+
+    //==================================================================
+    /// 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)(bbtk::BlackBox::Pointer,
+    ///                            const std::string&,
+    ///                            bbtk::IOStatus)
+    /// To pass a member function 'f' of an instance 'c' of a class 'C'
+    /// as callback you have to 'bind' it, i.e. call:
+    /// bbAddOutputObserver ( "Out", boost::bind( &C::f , c, _1, _2, _3 ) );
+    /// The convenience macro BBTK_BIND_OUTPUT_OBSERVER ( c, C::f ) does it for you
+    void bbAddOutputObserver(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 bbRemoveOutputObserver(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 !).
+    /// This method should be used by widgets in response
+    /// to user interaction when **ALL** outputs have been modified
+    /// (after the outputs has been updated !).
+    /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
+    /// ** USER INTENDED **
+    virtual void bbSignalOutputModification(bool reaction = true);
+    /// Signals that the BlackBox output "output_name" has been modified
+    /// (without marking the box as MODIFIED because its output state is ok : don't care if you understand : use it !).
+    /// This method should be used by widgets in response to user interaction
+    /// only when **ONE** output has been modified
+    /// (after the output has been updated !)
+    /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
+    /// ** USER INTENDED **
+    virtual void bbSignalOutputModification( const std::string& output_name,
+                                            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
+    /// (optimization issue).
+    /// (without marking the box as MODIFIED because its output state is ok).
+    /// This method should be used by widgets in response to user interaction
+    /// When more than one output has been changed but not all
+    /// (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);
+   //==================================================================
+    //@}
+
+
+
+
+
+
     //==================================================================
-    // Common inputs / outputs to all boxes
-    /// Returns the value of the input "BoxProcessMode"
+    /// @name Common inputs / outputs to all boxes
+    //@{
+    /// Returns the value of the input 'BoxProcessMode'
     std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
-    /// Sets the value of the input "BoxProcessMode"
+    /// Sets the value of the input 'BoxProcessMode'
     void bbSetInputBoxProcessMode(std::string a) { bbmBoxProcessMode = a; }
-    typedef enum
-      {
-       Pipeline,
-       Always,
-       Reactive
-      }
-      BoxProcessModeValue;
+    /// The possible values of the input 'BoxProcessMode'
+    typedef enum 
+     {
+      bbPipeline,
+      bbAlways,
+      bbReactive,
+         bbManual
+     }
+    BoxProcessModeValue;
+    
     /// Returns the "decoded" value of the input "BoxProcessMode"
     BoxProcessModeValue bbGetBoxProcessModeValue() const;
-  
+    /// Returns true iff the input 'BoxProcessMode' is set to 'Reactive' (or a synonym)
     virtual bool bbBoxProcessModeIsReactive() const;
-
+    /// Returns true iff the input 'BoxProcessMode' is set to 'Always' (or a synonym)
     virtual bool bbBoxProcessModeIsAlways() const;
+       /// Returns true iff the input 'BoxProcessMode' is set to 'Manual' (or a synonym)
+       virtual bool bbBoxProcessModeIsManual() const;
 
-    /// Returns the value of the input "Execute" 
+    /// Returns the value of the input 'BoxExecute'
     Void bbGetInputBoxExecute() { return Void(); }
-    /// Sets the value of the input "Execute"
-    void bbSetInputBoxExecute(Void = 0) {}
+    /// Sets the value of the input 'BoxExecute'
+         void bbSetInputBoxExecute(Void = 0) {  }
 
-    /// Returns the value of the output "Change"
+    /// Returns the value of the output 'BoxChange'
     Void bbGetOutputBoxChange() { return Void(); }
-    /// Sets the value of the output "Change" : signal a modification
-    void bbSetOutputBoxChange(Void = 0) { bbSetModifiedStatus(); }
-
-    //==================================================================    
-
+    /// Sets the value of the output 'BoxChange'
+    void bbSetOutputBoxChange(Void = 0) {  }
+    //@}
+    //==================================================================
 
-    //==================================================================    
+    virtual void bbPrintHelp(BlackBox::Pointer parentblackbox,
+                            int detail, int level
+                            );
 
     /// Does nothing here : overloaded in ComplexBlackBox
-    void bbInsertHTMLGraph(  std::ofstream& s, 
-                            int detail, 
+    void bbInsertHTMLGraph(  std::ofstream& s,
+                            int detail,
                             int level,
                             bool instanceOrtype,
                             const std::string& output_dir,
-                            bool relative_link ) 
+                            bool relative_link )
     {}
 
-    /// Write Graphviz-dot description in file. 
-    /// Here dumps a single box description (i/o) but overloaded 
-    /// in ComplexBlackBox to dump the internal pipeline representation 
+
+    //==================================================================
+    /// @name Window related methods
+    //@{
+    virtual void bbSetShown(bool) {}
+    virtual bool bbIsShown() { return false; }
+    //@}
+    //==================================================================
+
+    //JCP changed to public 09-06-09
+        //==================================================================
+            /// @name Manage the execution
+            //@{
+            static bool bbGlobalGetSomeBoxExecuting();
+            static void bbGlobalSetSomeBoxExecuting(bool b);
+
+            static void bbGlobalSetFreezeExecution(bool b);
+            static bool bbGlobalGetFreezeExecution();
+
+            static void bbGlobalAddToExecutionList( BlackBox::Pointer b );
+            static void bbGlobalProcessExecutionList();
+
+            //@}
+    //JCP 09-06-09
+
+  protected:
+
+   //==================================================================
+    /// @name User redefinable methods
+    ///  Virtual methods which can be redefined by inherited classes
+    //@{
+
+    //==================================================================
+    /// User can redefine this method to set
+    /// the default values of the box inputs and outputs
+    /// (it is called in the box constructor)
+    virtual void bbUserSetDefaultValues() {}
+
+    /// User can redefine this method to initialize what must be
+    /// initialized for the box to work, for example allocate dynamic data.
+    /// It is called once and only once before any call to bbUserCreateWidget
+    /// or bbUserProcess.
+    /// What has been allocated here must be desalocated in
+    /// bbFinalizeProcessing
+    virtual void bbUserInitializeProcessing() {}
+
+    /// User must redefine this method to uninitialize what has been
+    /// initialized in bbUserInitializeProcessing,
+    /// typically desallocate memory that has been allocated dynamically.
+    /// It is called in the box destructor if and only if (iff)
+    /// bbUserInitializeProcessing has been called previously.
+    virtual void bbUserFinalizeProcessing() {}
+    ///
+    virtual void bbUserOnShow() {}
+
+    //==================================================================
+    // @}
+    //==================================================================
+
+
+    //==================================================================
+
+    /// Write Graphviz-dot description in file.
+    /// Here dumps a single box description (i/o) but overloaded
+    /// in ComplexBlackBox to dump the internal pipeline representation
     /// recursing into internal boxes descriptions if level>0.
     /// detail = 1 : draw inputs and outputs (do not draw otherwise)
-    /// instanceOrtype = true : draw inputs and outputs VALUES 
+    /// instanceOrtype = true : draw inputs and outputs VALUES
     ///  (uses bbGetInputAsString / bbGetOutputAsString which use adaptors)
     /// If relative_link is true then creates relative hrefs
     virtual void bbWriteDotFileBlackBox(FILE *ff,
-                                       BlackBox::Pointer parentblackbox, 
-                                       int detail, int level, 
+                                       BlackBox::Pointer parentblackbox,
+                                       int detail, int level,
                                        bool instanceOrtype,
                                        bool relative_link );
     /// Auxiliary method for bbWriteDotFileBlackBox
     virtual void bbWriteDotInputOutputName(FILE *ff,
-                                          bool inputoutput, 
+                                          bool inputoutput,
                                           int detail, int level);
-    
-     
-    virtual void bbShowRelations(BlackBox::Pointer parentblackbox, 
-                                int detail, int level
-                                );
-    
-    std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
-    std::string bbGetInputAsString( const std::string &input); //,Factory *factory);
-    virtual BlackBox::Pointer bbFindBlackBox(const std::string &blackboxname) 
-    { return BlackBox::Pointer();}
+
+     virtual BlackBox::Pointer bbFindBlackBox(const std::string &blackboxname)
+              { return BlackBox::Pointer();}
 
     virtual void Check(bool recursive = true);
 
-  protected:
     //==================================================================
-    // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER 
+    // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER
     // (IN INHERITED CLASSES)
     /// Constructor that take the BlackBox's name
     BlackBox(const std::string &name);
-    /// Constructor from an existing box (copy) with a new name 
+    /// Constructor from an existing box (copy) with a new name
     BlackBox(BlackBox& from, const std::string &name);
     //==================================================================
 
 
-    //==================================================================
-    ///  Sets the status of the box
-    void bbSetStatus( IOStatus t) { bbmStatus = t; } 
-    //==================================================================
-    
-  private:
-    friend class Connection;
-    friend class ComplexBlackBox;
-
-    /// Sets the parent of the BlackBox
-    void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
-    
-
-    /// Connects the input <name> to the connection c
-    virtual void bbConnectInput( const std::string& name, 
-                                Connection* c);
-    /// Connects the output <name> to the connection c
-    virtual void bbConnectOutput( const std::string& name, 
-                                 Connection* c);
-    /// Disconnects the input <name> from the connection c
-    virtual void bbDisconnectInput( const std::string& name, 
-                                   Connection* c);
-    /// Disconnects the output <name> from the connection c
-    virtual void bbDisconnectOutput( const std::string& name, 
-                                    Connection* c);
-
 
+    //==================================================================
     /// @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).
-    /// The main method is bbBackwardUpdate which is called by bbExecute and implemented in UserBlackBox and ComplexBlackBox.
-    /// 
+    ///  Methods which participate to pipeline processing.
     //@{
-
-    //==================================================================   
-    /// Recursive pipeline processing in backward direction 
-    /// (recursion is in backward direction however execution always goes forward).
-    /// Pure virtual; defined in UserBlackBox 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
+    //==================================================================
+    /// Recursive execution method
     ///
-    /// 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;
+    /// \param caller : The connection which invoked the method; null if called by bbExecute
+    virtual void bbRecursiveExecute(Connection::Pointer caller);
     //==================================================================
 
     //==================================================================
-    /// 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;
+    /// Updates the BlackBox inputs
+    /// Calls RecursiveExecute on all BlackBoxInputConnector
+    /// \returns The maximum of final IOStatus after each input update
+    IOStatus bbUpdateInputs();
     //==================================================================
-  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);
+    /// Actual CreateWindow method (vitual)
+    /// Overloaded in AtomicBlacBox and descendants
+    virtual void bbCreateWindow()
+    {
+      //  bbtkError("BlackBox::bbCreateWidget called : how can this happen ?");
+    }
     //==================================================================
 
     //==================================================================
-    /// 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 ) { }
+    /// Actual ShowWindow method (vitual)
+    /// Overloaded in AtomicBlacBox and descendants
+    virtual void bbShowWindow()
+    {
+      //  bbtkError("BlackBox::bbShowWidget called : how can this happen ?");
+    }
     //==================================================================
 
-    //==================================================================
-    /// Specific methods for window creation during pipeline execution
-    /// Creates the window associated to the box (called after bbUpdateInputs)
-    /// Does nothing here. Overloaded in WxBlackBox.
-    // virtual void bbCreateWindow() { }
-    /// Shows the window associated to the box 
-    /// (called after bbProcess during bbExecute)
-    /// Does nothing here but overloaded in WxBlackBox and WxContainerBlackBox
-    virtual void bbShowWindow(Connection::Pointer caller) { }
-    virtual void bbHideWindow() {}
-    virtual void bbCloseWindow() { }
+
    //==================================================================
+    /// Actual processing method (vitual)
+    /// Overloaded in AtomicBlacBox and descendants
+    virtual void bbProcess()
+    {
+      bbtkError("BlackBox::bbProcess called : how can this happen ?");
+//      this->bbUserProcess();
+    }
+    //==================================================================
 
+    //==================================================================
+    /// Computes the final IOStatus of inputs and outputs after processing
+virtual    void bbComputePostProcessStatus();
     //@}
-  public: 
+    //==================================================================
+
 
-    static bool bbGlobalGetSomeBoxExecuting();
-    static void bbGlobalSetSomeBoxExecuting(bool b);
+    //==================================================================
+    /// 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);
+    //==================================================================
 
-    static void bbGlobalSetFreezeExecution(bool b);
-    static bool bbGlobalGetFreezeExecution();
 
-    /// Returns true if the box can "react",
-    /// which means execute in response to an input change 
-    virtual bool bbCanReact() const;
-    
-  protected:  
-    static void bbGlobalAddToExecutionList( BlackBox::Pointer b );
-    static void bbGlobalProcessExecutionList();
 
     //==================================================================
-  protected:
+    /// @name Box con(des)struction / initi(fin)alization methods
+    //@{
+
     //==================================================================
     /// Allocates the i/o connectors of the black box
     virtual void bbAllocateConnectors();
@@ -371,43 +516,136 @@ 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 
-    // (Releasing it in the destructor may cause dl close and crash)
-    /// Black box deleter 
+    //==================================================================
+    /// Initializes processing IF NEEDED.
+    /// Calls bbRecursiveInitializeProcessing if the box is in
+    /// "uninitialized" state and put it in "initialized" state.
+    /// On construction, boxes are "uninitialized".
+    /// See also bbFinalizeProcessing
+    void bbInitializeProcessing();
+
+    /// Finalizes processing IF NEEDED.
+    /// Calls bbRecursiveFinalizeProcessing if the box is in
+    /// "initialized" state and put it in "uninitialized" state.
+    /// On construction, boxes are "uninitialized".
+    /// See also bbInitializeProcessing
+    void bbFinalizeProcessing();
+
+    /// Abstract prototype of the method which
+    /// Recursively calls itself for the parent black box and then
+    /// calls bbUserInitializeProcessing for its own class.
+    /// It is redefined in each black box descendant.
+    /// Allows to call bbUserInitializeProcessing for all inherited classes
+    /// (like a constructor does)
+    virtual void bbRecursiveInitializeProcessing() {}
+
+
+    /// Abstract prototype of the method which
+    /// calls bbUserFinalizeProcessing for its own class and then
+    /// recursively calls itself for the parent black box.
+    /// It is redefined in each black box descendant.
+    /// Allows to call bbUserFinalizeProcessing for all inherited classes
+    /// (like a destructor does)
+    virtual void bbRecursiveFinalizeProcessing() {}
+    //==================================================================
+
+    //@}
+    //==================================================================
+
+  private:
+    //==================================================================
+    friend class Connection;
+    friend class ComplexBlackBox;
+
+    /// Sets the parent of the BlackBox
+    void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
+
+    //==================================================================
+    /// @name Input/output connection/disconnection
+    /// INTERNAL METHODS used by a Connection to connect/disconnect
+    /// itself to the i/o connectors of the box
+    //@{
+
+    /// Connects the input <name> to the connection c
+    virtual void bbConnectInput( const std::string& name, Connection* c);
+    /// Connects the output <name> to the connection c
+    virtual void bbConnectOutput( const std::string& name, Connection* c);
+    /// Disconnects the input <name> from the connection c
+    virtual void bbDisconnectInput( const std::string& name, Connection* c);
+    /// Disconnects the output <name> from the connection c
+    virtual void bbDisconnectOutput( const std::string& name, Connection* c);
+    //@}
+    //==================================================================
+
+    /// Returns true if the box can "react",
+    /// which means execute in response to an input change
+    virtual bool bbCanReact() const;
+
+    /// Returns true iff the box is executing
+    bool bbGetExecuting() const { return bbmExecuting; }
+    /// Sets the bbmExecuting bool returned by bbGetExecuting
+    void bbSetExecuting(bool b) { bbmExecuting = b; }
+
+    //==================================================================
+  protected:
+
+
+     //==================================================================
+    /// Black box objects have a special deleter
+    /// which must take care of releasing the descriptor
+    /// **AFTER** the box is deleted
+    /// (Releasing it in the destructor may cause dl close and crash)
+    /// Black box deleter
     /// 1) Calls the user overloadable bbDelete method
     /// 2) Releases the box descriptor
     struct BBTK_EXPORT Deleter : public Object::Deleter
-    { 
+    {
       Deleter();
-      void Delete(Object* p);
+      int Delete(Object* p);
     };
+    //==================================================================
 
+    //==================================================================
+    /// Like Object::MakePointer but returns a boost::shared_pointer which uses a BlackBox::Deleter to delete the object instead of the default Object::Deleter
     template <class U>
     static boost::shared_ptr<U> MakeBlackBoxPointer(U* s, bool lock = false)
     {
       return MakePointer(s,BlackBox::Deleter(),lock);
     }
+    //==================================================================
+
+    //==================================================================
+    /// Effective deletion method called by the Deleter.
+    /// The default implementation is to issue 'delete this'
+    /// but it can be redefined in inherited classes to handle special deletion mechanisms (e.g. ref counting, private destructors, such as vtk objects deletion with method Delete, etc.).
+    /// \return The number of remaining references on the object after the call (if meaningfull...): used by bbtk to warn a user if another smart pointing system is still holding the object...
+
+//JCP 21-09-20 09 delete this throws and exception change due to compiler version changing and boost version
+    virtual int bbDelete() { delete this; 
+                             return 0; }
+    //==================================================================
+
 
-    virtual void bbDelete() { delete this; }
+    //==================================================================
   private:
-    
     //==================================================================
-    // PRIVATE PART 
-    /// The status of the box
-    IOStatus bbmStatus;
+
+    //==================================================================
+    // ATTRIBUTES
+    /// Is the box initialized ?
+    bool bbmInitialized;
+    /// 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 : bbUpdate() 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
+       /// 3 : "Manual" mode
     std::string bbmBoxProcessMode;
-
     /// The parent of the black box in the ComplexBlackBox hierarchy
     BlackBox::WeakPointer bbmParent;
     //==================================================================
@@ -416,23 +654,21 @@ bool reaction = true);
    //==================================================================
     // ATTRIBUTES
     ///  Map that contains the output connectors of the black box
-    OutputConnectorMapType mOutputConnectorMap; 
+    OutputConnectorMapType mOutputConnectorMap;
     ///  Map that contains the input connectors of the black box
     InputConnectorMapType mInputConnectorMap;
     //==================================================================
-
-
+         
+         
+         bool bbLetRecursiveExecuteManualMode;
  };
   // Class BlackBox
 
 
+  /// Convenient macro to create output observer callbacks (freehand functions) from object and method pointer (see samples/SampleOutputObserver)
+#define BBTK_MAKE_OUTPUT_OBSERVER(OBJECT,METHOD) \
+    boost::bind( METHOD, OBJECT, _1, _2, _3)
 
-
-
-
-
 }
 // namespace bbtk
 #endif
-