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
{
class Factory;
class Connection;
+ class BlackBoxOutputConnector;
class BBTK_EXPORT BlackBox : public Object
{
//==================================================================
// 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*>
/// 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 !).
/// 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
/// (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
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;
/// 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; }
/// 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(); }
//==================================================================
//==================================================================
- /// 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;
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)
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
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;
//==================================================================
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