X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=kernel%2Fsrc%2FbbtkBlackBox.h;h=db02118273aaa83c2f12a3e7f912c656dca50d1e;hb=064072f6c392f24c17f71d459a9508408a806927;hp=48509a1930ac2e48a768f432e2e85f888611f36d;hpb=5934ccb7ca0fabdbe6c1907b2aea3696e19a0251;p=bbtk.git diff --git a/kernel/src/bbtkBlackBox.h b/kernel/src/bbtkBlackBox.h index 48509a1..db02118 100644 --- a/kernel/src/bbtkBlackBox.h +++ b/kernel/src/bbtkBlackBox.h @@ -1,79 +1,137 @@ +/* + # --------------------------------------------------------------------- + # + # 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/04/22 14:30:25 $ - Version: $Revision: 1.8 $ - - 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 +// Signal/slot mechanism for output change events +#include +#include + + +#define bbtkBlackBoxMessage(key,level,mess) \ + bbtkMessage(key,level,"["< OutputChangeSignalType; + typedef OutputChangeSignalType::slot_function_type + OutputChangeCallbackType; + /// The type of map of output connector pointers - typedef std::map + typedef std::map OutputConnectorMapType; /// The type of map of input connector pointers - typedef std::map + typedef std::map 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 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,285 +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& 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 + IOStatus bbGetInputStatus( const std::string &name ) const + { return mInputConnectorMap.find(name)->second->GetStatus(); } /// Gets the data of the input called virtual Data bbGetInput( const std::string &name ) = 0; + /// Gets the data of the input called 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 . + /// 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 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 virtual Data bbGetOutput( const std::string &name ) = 0; + /// Gets the data of the output called 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 . - /// 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 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& + 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 to the connection c - virtual void bbConnectInput( const std::string& name, - Connection* c); - /// Connects the output to the connection c - virtual void bbConnectOutput( const std::string& name, - Connection* c); - /// Disconnects the input from the connection c - virtual void bbDisconnectInput( const std::string& name, - Connection* c); - /// Disconnects the output 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() {} + //================================================================== + /// 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(); @@ -370,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 to the connection c + virtual void bbConnectInput( const std::string& name, Connection* c); + /// Connects the output to the connection c + virtual void bbConnectOutput( const std::string& name, Connection* c); + /// Disconnects the input from the connection c + virtual void bbDisconnectInput( const std::string& name, Connection* c); + /// Disconnects the output 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 Deleter : public Object::Deleter - { + 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 static boost::shared_ptr 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; //================================================================== @@ -415,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 -