1 /*=========================================================================
4 Module: $RCSfile: bbtkBlackBox.h,v $
6 Date: $Date: 2008/03/11 18:46:47 $
7 Version: $Revision: 1.3 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See doc/license.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
22 * \brief Class bbtk::BlackBox : abstract black-box interface.
26 * \class bbtk::BlackBox
27 * \brief Abstract black-box interface
30 #ifndef __bbtkBlackBox_h__
31 #define __bbtkBlackBox_h__
33 #include "bbtkSystem.h"
34 #include "bbtkBlackBoxDescriptor.h"
35 //#include "bbtkConnection.h"
36 #include "bbtkBlackBoxInputConnector.h"
37 #include "bbtkBlackBoxOutputConnector.h"
44 struct Void { Void(int = 0) {} };
48 class BBTK_EXPORT BlackBox
53 //==================================================================
55 //==================================================================
56 /// The type of pointer on a BlackBox
57 typedef BlackBox* Pointer;
59 /// The type of map of output connector pointers
60 typedef std::map<std::string, BlackBoxOutputConnector*>
61 OutputConnectorMapType;
62 /// The type of map of input connector pointers
63 typedef std::map<std::string, BlackBoxInputConnector*>
64 InputConnectorMapType;
66 /// Returns the pointer on the descriptor of the box
67 virtual BlackBoxDescriptor* bbGetDescriptor() const = 0;
69 /// Returns a pointer on a clone of the box with name <name>
70 virtual BlackBox* bbClone(const std::string& name) = 0;
72 /// Destruction method of a black box
73 virtual void bbDelete();
74 /// User overloadable destruction method of a black box
75 virtual void bbUserDelete();
77 /// Returns the Name of the Type of the BlackBox
78 const std::string& bbGetTypeName() const
79 { return bbGetDescriptor()->GetTypeName(); }
82 /// Returns the name of the BlackBox (instance)
83 const std::string& bbGetName() const { return bbmName; }
85 /// Returns the full name of the BlackBox (instance+type)
86 virtual std::string bbGetFullName() const;
88 /// Returns the name with the name of the parent prepended if any
89 std::string bbGetNameWithParent() const;
91 /// Sets the parent of the BlackBox
92 void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
93 /// Returns the parent of the BlackBox, i.e the BlackBox that contains it (0 if none)
94 BlackBox::Pointer bbGetParent() const { return bbmParent; }
97 /// Main processing method of the box.
98 virtual void bbExecute(bool force = false);
100 /// Signals that the BlackBox has been modified through the input connector c
101 /// and propagates it downward
102 virtual void bbSetModifiedStatus(BlackBoxInputConnector* c = 0);
103 /// Signals that the BlackBox outputs have been modified
104 /// without marking the box as MODIFIED because its output state is ok.
105 /// This method should be used by widgets in response
106 /// to user interaction when **ALL** outputs have been modified
107 /// (after the outputs has been updated !)
108 virtual void bbSignalOutputModification(bool reaction = true);
109 /// Signals that the BlackBox output "output_name" have been modified
110 /// without marking the box as MODIFIED because its output state is ok.
111 /// This method should be used by widgets in response to user interaction
112 /// only when **ONE** output has been modified
113 /// (after the output has been updated !)
114 virtual void bbSignalOutputModification( const std::string& output_name,
115 bool reaction = true);
116 /// Signals that the BlackBox vector of outputs "output_name"
117 /// have been modified
118 /// without marking the box as MODIFIED because its output state is ok.
119 /// This method should be used by widgets in response to user interaction
120 /// When more than one output has been changed but not all
121 /// (after the outputs have been updated of course!)
122 virtual void bbSignalOutputModification( const std::vector<std::string>& output_name,
123 bool reaction = true);
125 /// Gets the status of the box
126 virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
129 /// Returns true iff the BlackBox has an input of name label
130 virtual bool bbHasInput(const std::string& label) const;
131 /// Returns true iff the BlackBox has an output of name label
132 virtual bool bbHasOutput(const std::string& label) const;
134 /// Gets the input type of a given label
135 virtual TypeInfo bbGetInputType( const std::string &label ) const;
136 /// Gets the output type of a given label
137 virtual TypeInfo bbGetOutputType( const std::string &label ) const;
139 /// Gets the data of the input called <name>
140 virtual Data bbGetInput( const std::string &name ) = 0;
141 /// Gets the data of the output called <name>
142 virtual Data bbGetOutput( const std::string &name ) = 0;
144 /// Sets the data of the input called <name>.
145 /// If setModified is false then does not call bbSetModifiedStatus()
146 virtual void bbSetInput( const std::string &name, Data data,
147 bool setModified = true ) = 0;
148 virtual void bbBruteForceSetInputPointer( const std::string &name,
150 bool setModified = true) =0;
151 /// Sets the data of the output called <name>
152 virtual void bbSetOutput( const std::string &name, Data data) = 0;
154 /// Connects the input <name> to the connection c
155 virtual void bbConnectInput( const std::string& name, Connection* c);
156 /// Connects the output <name> to the connection c
157 virtual void bbConnectOutput( const std::string& name, Connection* c);
159 /// Disconnects the input <name> from the connection c
160 virtual void bbDisconnectInput( const std::string& name, Connection* c);
161 /// Disconnects the output <name> from the connection c
162 virtual void bbDisconnectOutput( const std::string& name, Connection* c);
164 /// Returns the input connectors map
165 InputConnectorMapType& bbGetInputConnectorMap()
166 { return mInputConnectorMap; }
167 /// Returns the output connectors map
168 OutputConnectorMapType& bbGetOutputConnectorMap()
169 { return mOutputConnectorMap; }
170 /// Returns the input connectors map (const)
171 const InputConnectorMapType& bbGetInputConnectorMap() const
172 { return mInputConnectorMap; }
173 /// Returns the output connectors map (const)
174 const OutputConnectorMapType& bbGetOutputConnectorMap() const
175 { return mOutputConnectorMap; }
178 /// Prints the Help on the BlackBox type
179 virtual void bbGetHelp(bool full=true) const;
182 //==================================================================
183 // Common inputs / outputs to all boxes
184 /// Returns the value of the input "BoxProcessMode"
185 std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
186 /// Sets the value of the input "BoxProcessMode"
187 void bbSetInputBoxProcessMode(std::string a) { bbmBoxProcessMode = a; }
195 /// Returns the "decoded" value of the input "BoxProcessMode"
196 BoxProcessModeValue bbGetBoxProcessModeValue() const;
198 virtual bool bbBoxProcessModeIsReactive() const;
200 virtual bool bbBoxProcessModeIsAlways() const;
202 /// Returns the value of the input "Execute"
203 Void bbGetInputBoxExecute() { return Void(); }
204 /// Sets the value of the input "Execute"
205 void bbSetInputBoxExecute(Void = 0) {}
207 /// Returns the value of the output "Change"
208 Void bbGetOutputBoxChange() { return Void(); }
209 /// Sets the value of the output "Change" : signal a modification
210 void bbSetOutputBoxChange(Void = 0) { bbSetModifiedStatus(); }
212 //==================================================================
215 //==================================================================
217 /// Does nothing here : overloaded in ComplexBlackBox
218 void bbInsertHTMLGraph( std::ofstream& s,
222 const std::string& output_dir,
226 /// Write Graphviz-dot description in file.
227 /// Here dumps a single box description (i/o) but overloaded
228 /// in ComplexBlackBox to dump the internal pipeline representation
229 /// recursing into internal boxes descriptions if level>0.
230 /// detail = 1 : draw inputs and outputs (do not draw otherwise)
231 /// instanceOrtype = true : draw inputs and outputs VALUES
232 /// (uses bbGetInputAsString / bbGetOutputAsString which use adaptors)
233 /// If relative_link is true then creates relative hrefs
234 virtual void bbWriteDotFileBlackBox(FILE *ff,
235 BlackBox *parentblackbox,
236 int detail, int level,
238 bool relative_link );
239 /// Auxiliary method for bbWriteDotFileBlackBox
240 virtual void bbWriteDotInputOutputName(FILE *ff,
242 int detail, int level);
245 virtual void bbShowRelations(BlackBox *parentblackbox,
246 int detail, int level
249 std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
250 std::string bbGetInputAsString( const std::string &input); //,Factory *factory);
251 virtual BlackBox *bbFindBlackBox(const std::string &blackboxname) { return NULL;}
254 //==================================================================
255 // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER
256 // (IN INHERITED CLASSES)
257 /// Constructor that take the BlackBox's name
258 BlackBox(const std::string &name);
259 /// Constructor from an existing box (copy) with a new name
260 BlackBox(BlackBox& from, const std::string &name);
263 //==================================================================
266 //==================================================================
267 /// Sets the status of the box
268 void bbSetStatus( IOStatus t) { bbmStatus = t; }
269 //==================================================================
273 /// @name Pipeline processing methods
274 /// Methods which participate to (forward or backward) pipeline processing.
275 /// 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).
276 /// The main method is bbBackwardUpdate which is called by bbExecute and implemented in UserBlackBox and ComplexBlackBox.
280 //==================================================================
281 /// Recursive pipeline processing in backward direction
282 /// (recursion is in backward direction however execution always goes forward).
283 /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
285 /// \returns The final status of the box (UPTODATE or MODIFIED)
286 /// \param caller : The connection which invoked the method; null if called by bbExecute
288 /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
290 /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on upstream boxes)
291 /// - calls bbCreateWidget
292 /// - calls bbProcess which is the user callback which does the actual processing
293 /// - calls bbUpdateChildren
294 /// - calls bbShowWidget which shows the widget associated to the box (if any)
296 virtual IOStatus bbBackwardUpdate(Connection* caller) = 0;
297 //==================================================================
299 //==================================================================
300 /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
301 /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
303 /// \param caller : The connection which invoked the method
305 /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
307 /// - calls bbCreateWidget
308 /// - calls bbProcess which is the user callback which does the actual processing
309 /// - calls bbUpdateChildren which recursively calls bbForwardUpdate on connections attached the "Child" output
310 // virtual void bbForwardUpdate(Connection* caller) = 0;
311 //==================================================================
313 //==================================================================
314 /// Updates the BlackBox inputs and returns the final status of the inputs
315 /// (==UPTODATE iff all inputs are UPTODATE)
316 // If excludeParent == true then excludes the upstream box connected to input 'Parent' from recursive update
317 IOStatus bbUpdateInputs(bool excludeParent=false);
318 //==================================================================
320 //==================================================================
321 /// Updates the pipeline in upstream-downstream direction along the "Child"-"Parent" connections only.
322 /// Does nothing here. Overloaded in WxContainerBlackbox
323 //virtual void bbUpdateChildren( Connection* caller ) { }
324 //==================================================================
326 //==================================================================
327 /// Specific methods for window creation during pipeline execution
328 /// Creates the window associated to the box (called after bbUpdateInputs)
329 /// Does nothing here. Overloaded in WxBlackBox.
330 // virtual void bbCreateWindow() { }
331 /// Shows the window associated to the box
332 /// (called after bbProcess during bbExecute)
333 /// Does nothing here but overloaded in WxBlackBox and WxContainerBlackBox
334 virtual void bbShowWindow(Connection* caller) { }
336 virtual void bbHideWindow() {}
337 //==================================================================
342 static bool bbGlobalGetSomeBoxExecuting();
343 static void bbGlobalSetSomeBoxExecuting(bool b);
345 static void bbGlobalSetFreezeExecution(bool b);
346 static bool bbGlobalGetFreezeExecution();
348 /// Returns true if the box can "react",
349 /// which means execute in response to an input change
350 virtual bool bbCanReact() const;
353 static void bbGlobalAddToExecutionList( BlackBox* b );
354 static void bbGlobalProcessExecutionList();
356 //==================================================================
358 //==================================================================
359 /// Allocates the i/o connectors of the black box
360 virtual void bbAllocateConnectors();
361 /// Desallocates the i/o connectors of the black box
362 virtual void bbDesallocateConnectors();
363 /// Copies the values of the inputs/output from the BlackBox from
364 virtual void bbCopyIOValues(BlackBox& from);
365 //==================================================================
370 //==================================================================
372 /// Default constructor is private : derived classes must use the constructor with the BlackBox's name
374 /// The status of the box
376 /// The name of the black-box
378 /// The name of the package to which it belongs
379 std::string bbmPackageName;
381 /// 0 : "Pipeline" mode : bbUpdate() only calls Process if Status == MODIFIED (normal pipeline processing)
382 /// 1 : "Always" mode : bbUpdate() always calls Process
383 /// 2 : "Reactive" mode : bbSetModifiedStatus() calls bbUpdate()
384 std::string bbmBoxProcessMode;
386 /// The parent of the black box in the ComplexBlackBox hierarchy
387 BlackBox::Pointer bbmParent;
388 //==================================================================
390 //==================================================================
392 /// Map that contains the output connectors of the black box
393 OutputConnectorMapType mOutputConnectorMap;
394 /// Map that contains the input connectors of the black box
395 InputConnectorMapType mInputConnectorMap;
396 //==================================================================
399 static bool bbmgSomeBoxExecuting;
400 static bool bbmgFreezeExecution;
401 static std::set<BlackBox*> bbmgExecutionList;