1 /*=========================================================================
4 Module: $RCSfile: bbtkBlackBox.h,v $
6 Date: $Date: 2008/01/22 15:02:00 $
7 Version: $Revision: 1.1 $
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 "bbtkBlackBoxDescriptor.h"
34 //#include "bbtkConnection.h"
35 #include "bbtkBlackBoxInputConnector.h"
36 #include "bbtkBlackBoxOutputConnector.h"
43 struct Void { Void(int = 0) {} };
47 class BBTK_EXPORT BlackBox
52 //==================================================================
54 //==================================================================
55 /// The type of pointer on a BlackBox
56 typedef BlackBox* Pointer;
58 /// The type of map of output connector pointers
59 typedef std::map<std::string, BlackBoxOutputConnector*>
60 OutputConnectorMapType;
61 /// The type of map of input connector pointers
62 typedef std::map<std::string, BlackBoxInputConnector*>
63 InputConnectorMapType;
65 /// Returns the pointer on the descriptor of the box
66 virtual BlackBoxDescriptor* bbGetDescriptor() const = 0;
68 /// Returns a pointer on a clone of the box with name <name>
69 virtual BlackBox* bbClone(const std::string& name) = 0;
71 /// Destruction method of a black box
72 virtual void bbDelete();
73 /// User overloadable destruction method of a black box
74 virtual void bbUserDelete();
76 /// Returns the Name of the Type of the BlackBox
77 const std::string& bbGetTypeName() const
78 { return bbGetDescriptor()->GetTypeName(); }
81 /// Returns the name of the BlackBox (instance)
82 const std::string& bbGetName() const { return bbmName; }
84 /// Returns the full name of the BlackBox (instance+type)
85 virtual std::string bbGetFullName() const;
87 /// Returns the name with the name of the parent prepended if any
88 std::string bbGetNameWithParent() const;
90 /// Sets the parent of the BlackBox
91 void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
92 /// Returns the parent of the BlackBox, i.e the BlackBox that contains it (0 if none)
93 BlackBox::Pointer bbGetParent() const { return bbmParent; }
96 /// Main processing method of the box.
97 virtual void bbExecute(bool force = false);
99 /// Signals that the BlackBox has been modified through the input connector c
100 /// and propagates it downward
101 virtual void bbSetModifiedStatus(BlackBoxInputConnector* c = 0);
102 /// Signals that the BlackBox outputs have been modified
103 /// without marking the box as MODIFIED because its output state is ok.
104 /// This method should be used by widgets in response
105 /// to user interaction when **ALL** outputs have been modified
106 /// (after the outputs has been updated !)
107 virtual void bbSignalOutputModification(bool reaction = true);
108 /// Signals that the BlackBox output "output_name" have been modified
109 /// without marking the box as MODIFIED because its output state is ok.
110 /// This method should be used by widgets in response to user interaction
111 /// only when **ONE** output has been modified
112 /// (after the output has been updated !)
113 virtual void bbSignalOutputModification( const std::string& output_name,
114 bool reaction = true);
115 /// Signals that the BlackBox vector of outputs "output_name"
116 /// have been modified
117 /// without marking the box as MODIFIED because its output state is ok.
118 /// This method should be used by widgets in response to user interaction
119 /// When more than one output has been changed but not all
120 /// (after the outputs have been updated of course!)
121 virtual void bbSignalOutputModification( const std::vector<std::string>& output_name,
122 bool reaction = true);
124 /// Gets the status of the box
125 virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
128 /// Returns true iff the BlackBox has an input of name label
129 virtual bool bbHasInput(const std::string& label) const;
130 /// Returns true iff the BlackBox has an output of name label
131 virtual bool bbHasOutput(const std::string& label) const;
133 /// Gets the input type of a given label
134 virtual TypeInfo bbGetInputType( const std::string &label ) const;
135 /// Gets the output type of a given label
136 virtual TypeInfo bbGetOutputType( const std::string &label ) const;
138 /// Gets the data of the input called <name>
139 virtual Data bbGetInput( const std::string &name ) = 0;
140 /// Gets the data of the output called <name>
141 virtual Data bbGetOutput( const std::string &name ) = 0;
143 /// Sets the data of the input called <name>.
144 /// If setModified is false then does not call bbSetModifiedStatus()
145 virtual void bbSetInput( const std::string &name, Data data,
146 bool setModified = true ) = 0;
147 virtual void bbBruteForceSetInputPointer( const std::string &name,
149 bool setModified = true) =0;
150 /// Sets the data of the output called <name>
151 virtual void bbSetOutput( const std::string &name, Data data) = 0;
153 /// Connects the input <name> to the connection c
154 virtual void bbConnectInput( const std::string& name, Connection* c);
155 /// Connects the output <name> to the connection c
156 virtual void bbConnectOutput( const std::string& name, Connection* c);
158 /// Disconnects the input <name> from the connection c
159 virtual void bbDisconnectInput( const std::string& name, Connection* c);
160 /// Disconnects the output <name> from the connection c
161 virtual void bbDisconnectOutput( const std::string& name, Connection* c);
163 /// Returns the input connectors map
164 InputConnectorMapType& bbGetInputConnectorMap()
165 { return mInputConnectorMap; }
166 /// Returns the output connectors map
167 OutputConnectorMapType& bbGetOutputConnectorMap()
168 { return mOutputConnectorMap; }
169 /// Returns the input connectors map (const)
170 const InputConnectorMapType& bbGetInputConnectorMap() const
171 { return mInputConnectorMap; }
172 /// Returns the output connectors map (const)
173 const OutputConnectorMapType& bbGetOutputConnectorMap() const
174 { return mOutputConnectorMap; }
177 /// Prints the Help on the BlackBox type
178 virtual void bbGetHelp(bool full=true) const;
181 //==================================================================
182 // Common inputs / outputs to all boxes
183 /// Returns the value of the input "BoxProcessMode"
184 std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
185 /// Sets the value of the input "BoxProcessMode"
186 void bbSetInputBoxProcessMode(std::string a) { bbmBoxProcessMode = a; }
194 /// Returns the "decoded" value of the input "BoxProcessMode"
195 BoxProcessModeValue bbGetBoxProcessModeValue() const;
197 virtual bool bbBoxProcessModeIsReactive() const;
199 virtual bool bbBoxProcessModeIsAlways() const;
201 /// Returns the value of the input "Execute"
202 Void bbGetInputBoxExecute() { return Void(); }
203 /// Sets the value of the input "Execute"
204 void bbSetInputBoxExecute(Void = 0) {}
206 /// Returns the value of the output "Change"
207 Void bbGetOutputBoxChange() { return Void(); }
208 /// Sets the value of the output "Change" : signal a modification
209 void bbSetOutputBoxChange(Void = 0) { bbSetModifiedStatus(); }
211 //==================================================================
214 //==================================================================
216 /// Does nothing here : overloaded in ComplexBlackBox
217 void bbInsertHTMLGraph( std::ofstream& s,
221 const std::string& output_dir,
225 /// Write Graphviz-dot description in file.
226 /// Here dumps a single box description (i/o) but overloaded
227 /// in ComplexBlackBox to dump the internal pipeline representation
228 /// recursing into internal boxes descriptions if level>0.
229 /// detail = 1 : draw inputs and outputs (do not draw otherwise)
230 /// instanceOrtype = true : draw inputs and outputs VALUES
231 /// (uses bbGetInputAsString / bbGetOutputAsString which use adaptors)
232 /// If relative_link is true then creates relative hrefs
233 virtual void bbWriteDotFileBlackBox(FILE *ff,
234 BlackBox *parentblackbox,
235 int detail, int level,
237 bool relative_link );
238 /// Auxiliary method for bbWriteDotFileBlackBox
239 virtual void bbWriteDotInputOutputName(FILE *ff,
241 int detail, int level);
244 virtual void bbShowRelations(BlackBox *parentblackbox,
245 int detail, int level
248 std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
249 std::string bbGetInputAsString( const std::string &input); //,Factory *factory);
250 virtual BlackBox *bbFindBlackBox(const std::string &blackboxname) { return NULL;}
253 //==================================================================
254 // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER
255 // (IN INHERITED CLASSES)
256 /// Constructor that take the BlackBox's name
257 BlackBox(const std::string &name);
258 /// Constructor from an existing box (copy) with a new name
259 BlackBox(BlackBox& from, const std::string &name);
262 //==================================================================
265 //==================================================================
266 /// Sets the status of the box
267 void bbSetStatus( IOStatus t) { bbmStatus = t; }
268 //==================================================================
272 /// @name Pipeline processing methods
273 /// Methods which participate to (forward or backward) pipeline processing.
274 /// 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).
275 /// The main method is bbBackwardUpdate which is called by bbExecute and implemented in UserBlackBox and ComplexBlackBox.
279 //==================================================================
280 /// Recursive pipeline processing in backward direction
281 /// (recursion is in backward direction however execution always goes forward).
282 /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
284 /// \returns The final status of the box (UPTODATE or MODIFIED)
285 /// \param caller : The connection which invoked the method; null if called by bbExecute
287 /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
289 /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on amont boxes)
290 /// - calls bbCreateWidget
291 /// - calls bbProcess which is the user callback which does the actual processing
292 /// - calls bbUpdateChildren
293 /// - calls bbShowWidget which shows the widget associated to the box (if any)
295 virtual IOStatus bbBackwardUpdate(Connection* caller) = 0;
296 //==================================================================
298 //==================================================================
299 /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
300 /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
302 /// \param caller : The connection which invoked the method
304 /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
306 /// - calls bbCreateWidget
307 /// - calls bbProcess which is the user callback which does the actual processing
308 /// - calls bbUpdateChildren which recursively calls bbForwardUpdate on connections attached the "Child" output
309 // virtual void bbForwardUpdate(Connection* caller) = 0;
310 //==================================================================
312 //==================================================================
313 /// Updates the BlackBox inputs and returns the final status of the inputs
314 /// (==UPTODATE iff all inputs are UPTODATE)
315 // If excludeParent == true then excludes the amont box connected to input 'Parent' from recursive update
316 IOStatus bbUpdateInputs(bool excludeParent=false);
317 //==================================================================
319 //==================================================================
320 /// Updates the pipeline in amont-aval direction along the "Child"-"Parent" connections only.
321 /// Does nothing here. Overloaded in WxContainerBlackbox
322 //virtual void bbUpdateChildren( Connection* caller ) { }
323 //==================================================================
325 //==================================================================
326 /// Specific methods for window creation during pipeline execution
327 /// Creates the window associated to the box (called after bbUpdateInputs)
328 /// Does nothing here. Overloaded in WxBlackBox.
329 // virtual void bbCreateWindow() { }
330 /// Shows the window associated to the box
331 /// (called after bbProcess during bbExecute)
332 /// Does nothing here but overloaded in WxBlackBox and WxContainerBlackBox
333 virtual void bbShowWindow(Connection* caller) { }
335 virtual void bbHideWindow() {}
336 //==================================================================
341 static bool bbGlobalGetSomeBoxExecuting()
342 { return bbmgSomeBoxExecuting; }
343 static void bbGlobalSetSomeBoxExecuting(bool b)
344 { bbmgSomeBoxExecuting = b; }
347 static void bbGlobalSetFreezeExecution(bool b) { bbmgFreezeExecution = b;}
348 static bool bbGlobalGetFreezeExecution() { return bbmgFreezeExecution; }
350 /// Returns true if the box can "react",
351 /// which means execute in response to an input change
352 virtual bool bbCanReact() const;
355 static void bbGlobalAddToExecutionList( BlackBox* b )
357 bbmgExecutionList.insert(b);
360 static void bbGlobalProcessExecutionList();
362 //==================================================================
364 //==================================================================
365 /// Allocates the i/o connectors of the black box
366 virtual void bbAllocateConnectors();
367 /// Desallocates the i/o connectors of the black box
368 virtual void bbDesallocateConnectors();
369 /// Copies the values of the inputs/output from the BlackBox from
370 virtual void bbCopyIOValues(BlackBox& from);
371 //==================================================================
376 //==================================================================
378 /// Default constructor is private : derived classes must use the constructor with the BlackBox's name
380 /// The status of the box
382 /// The name of the black-box
384 /// The name of the package to which it belongs
385 std::string bbmPackageName;
387 /// 0 : "Pipeline" mode : bbUpdate() only calls Process if Status == MODIFIED (normal pipeline processing)
388 /// 1 : "Always" mode : bbUpdate() always calls Process
389 /// 2 : "Reactive" mode : bbSetModifiedStatus() calls bbUpdate()
390 std::string bbmBoxProcessMode;
392 /// The parent of the black box in the ComplexBlackBox hierarchy
393 BlackBox::Pointer bbmParent;
394 //==================================================================
396 //==================================================================
398 /// Map that contains the output connectors of the black box
399 OutputConnectorMapType mOutputConnectorMap;
400 /// Map that contains the input connectors of the black box
401 InputConnectorMapType mInputConnectorMap;
402 //==================================================================
405 static bool bbmgSomeBoxExecuting;
406 static bool bbmgFreezeExecution;
409 static std::set<BlackBox*> bbmgExecutionList;