1 /*=========================================================================
4 Module: $RCSfile: bbtkBlackBox.h,v $
6 Date: $Date: 2008/10/06 09:11:21 $
7 Version: $Revision: 1.12 $
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 "bbtkBlackBoxInputConnector.h"
36 #include "bbtkBlackBoxOutputConnector.h"
43 struct Void { Void(int = 0) {} };
48 class BBTK_EXPORT BlackBox : public Object
50 BBTK_ABSTRACT_OBJECT_INTERFACE(BlackBox);
52 //==================================================================
54 //==================================================================
56 /// The type of map of output connector pointers
57 typedef std::map<std::string, BlackBoxOutputConnector*>
58 OutputConnectorMapType;
59 /// The type of map of input connector pointers
60 typedef std::map<std::string, BlackBoxInputConnector*>
61 InputConnectorMapType;
63 /// Returns the pointer on the descriptor of the box
64 virtual BlackBoxDescriptor::Pointer bbGetDescriptor() const = 0;
66 /// Returns a pointer on a clone of the box with name <name>
67 virtual BlackBox::Pointer bbClone(const std::string& name) = 0;
69 /// User overloadable destruction method of a black box
70 virtual void bbUserDelete();
72 /// Returns the Name of the Type of the BlackBox
73 const std::string& bbGetTypeName() const
74 { return bbGetDescriptor()->GetTypeName(); }
77 /// Returns the name of the BlackBox (instance)
78 const std::string& bbGetName() const { return bbmName; }
80 /// Returns the full name of the BlackBox (instance+type)
81 virtual std::string bbGetFullName() const;
83 /// Returns the name with the name of the parent prepended if any
84 virtual std::string bbGetNameWithParent() const;
86 /// Returns the parent of the BlackBox, i.e the BlackBox that contains it (0 if none)
87 BlackBox::Pointer bbGetParent() const { return bbmParent.lock(); }
90 /// Main processing method of the box.
91 virtual void bbExecute(bool force = false);
93 /// Signals that the BlackBox has been modified through the input connector c
94 /// and propagates it downward
95 virtual void bbSetModifiedStatus(BlackBoxInputConnector* c = 0);
96 /// Signals that the BlackBox outputs have been modified
97 /// without marking the box as MODIFIED because its output state is ok.
98 /// This method should be used by widgets in response
99 /// to user interaction when **ALL** outputs have been modified
100 /// (after the outputs has been updated !)
101 virtual void bbSignalOutputModification(bool reaction = true);
102 /// Signals that the BlackBox output "output_name" 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 to user interaction
105 /// only when **ONE** output has been modified
106 /// (after the output has been updated !)
107 virtual void bbSignalOutputModification( const std::string& output_name,
108 bool reaction = true);
109 /// Signals that the BlackBox vector of outputs "output_name"
110 /// have been modified
111 /// without marking the box as MODIFIED because its output state is ok.
112 /// This method should be used by widgets in response to user interaction
113 /// When more than one output has been changed but not all
114 /// (after the outputs have been updated of course!)
115 virtual void bbSignalOutputModification( const std::vector<std::string>& output_name,
116 bool reaction = true);
118 /// Gets the status of the box
119 virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
122 /// Returns true iff the BlackBox has an input of name label
123 virtual bool bbHasInput(const std::string& label) const;
124 /// Returns true iff the BlackBox has an output of name label
125 virtual bool bbHasOutput(const std::string& label) const;
127 /// Gets the input type of a given label
128 virtual TypeInfo bbGetInputType( const std::string &label ) const;
129 /// Gets the output type of a given label
130 virtual TypeInfo bbGetOutputType( const std::string &label ) const;
132 /// Gets the data of the input called <name>
133 virtual Data bbGetInput( const std::string &name ) = 0;
134 /// Gets the data of the output called <name>
135 virtual Data bbGetOutput( const std::string &name ) = 0;
137 /// Sets the data of the input called <name>.
138 /// If setModified is false then does not call bbSetModifiedStatus()
139 virtual void bbSetInput( const std::string &name, Data data,
140 bool setModified = true ) = 0;
141 virtual void bbBruteForceSetInputPointer( const std::string &name,
143 bool setModified = true) =0;
144 /// Sets the data of the output called <name>
145 virtual void bbSetOutput( const std::string &name, Data data) = 0;
148 /// Returns the input connectors map
149 InputConnectorMapType& bbGetInputConnectorMap()
150 { return mInputConnectorMap; }
151 /// Returns the output connectors map
152 OutputConnectorMapType& bbGetOutputConnectorMap()
153 { return mOutputConnectorMap; }
154 /// Returns the input connectors map (const)
155 const InputConnectorMapType& bbGetInputConnectorMap() const
156 { return mInputConnectorMap; }
157 /// Returns the output connectors map (const)
158 const OutputConnectorMapType& bbGetOutputConnectorMap() const
159 { return mOutputConnectorMap; }
162 /// Prints the Help on the BlackBox type
163 virtual void bbGetHelp(bool full=true) const;
166 //==================================================================
167 // Common inputs / outputs to all boxes
168 /// Returns the value of the input "BoxProcessMode"
169 std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
170 /// Sets the value of the input "BoxProcessMode"
171 void bbSetInputBoxProcessMode(std::string a) { bbmBoxProcessMode = a; }
179 /// Returns the "decoded" value of the input "BoxProcessMode"
180 BoxProcessModeValue bbGetBoxProcessModeValue() const;
182 virtual bool bbBoxProcessModeIsReactive() const;
184 virtual bool bbBoxProcessModeIsAlways() const;
186 /// Returns the value of the input "Execute"
187 Void bbGetInputBoxExecute() { return Void(); }
188 /// Sets the value of the input "Execute"
189 void bbSetInputBoxExecute(Void = 0) {}
191 /// Returns the value of the output "Change"
192 Void bbGetOutputBoxChange() { return Void(); }
193 /// Sets the value of the output "Change" : signal a modification
194 void bbSetOutputBoxChange(Void = 0) { bbSetModifiedStatus(); }
196 //==================================================================
199 //==================================================================
201 /// Does nothing here : overloaded in ComplexBlackBox
202 void bbInsertHTMLGraph( std::ofstream& s,
206 const std::string& output_dir,
210 /// Write Graphviz-dot description in file.
211 /// Here dumps a single box description (i/o) but overloaded
212 /// in ComplexBlackBox to dump the internal pipeline representation
213 /// recursing into internal boxes descriptions if level>0.
214 /// detail = 1 : draw inputs and outputs (do not draw otherwise)
215 /// instanceOrtype = true : draw inputs and outputs VALUES
216 /// (uses bbGetInputAsString / bbGetOutputAsString which use adaptors)
217 /// If relative_link is true then creates relative hrefs
218 virtual void bbWriteDotFileBlackBox(FILE *ff,
219 BlackBox::Pointer parentblackbox,
220 int detail, int level,
222 bool relative_link );
223 /// Auxiliary method for bbWriteDotFileBlackBox
224 virtual void bbWriteDotInputOutputName(FILE *ff,
226 int detail, int level);
229 virtual void bbShowRelations(BlackBox::Pointer parentblackbox,
230 int detail, int level
233 std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
234 std::string bbGetInputAsString( const std::string &input); //,Factory *factory);
235 virtual BlackBox::Pointer bbFindBlackBox(const std::string &blackboxname)
236 { return BlackBox::Pointer();}
238 virtual void Check(bool recursive = true);
240 virtual void bbUserOnShow() { }
241 void bbUserOnShowWidget(std::string nameInput);
245 //==================================================================
246 // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER
247 // (IN INHERITED CLASSES)
248 /// Constructor that take the BlackBox's name
249 BlackBox(const std::string &name);
250 /// Constructor from an existing box (copy) with a new name
251 BlackBox(BlackBox& from, const std::string &name);
252 //==================================================================
255 //==================================================================
256 /// Sets the status of the box
257 void bbSetStatus( IOStatus t) { bbmStatus = t; }
258 //==================================================================
261 friend class Connection;
262 friend class ComplexBlackBox;
264 /// Sets the parent of the BlackBox
265 void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
268 /// Connects the input <name> to the connection c
269 virtual void bbConnectInput( const std::string& name,
271 /// Connects the output <name> to the connection c
272 virtual void bbConnectOutput( const std::string& name,
274 /// Disconnects the input <name> from the connection c
275 virtual void bbDisconnectInput( const std::string& name,
277 /// Disconnects the output <name> from the connection c
278 virtual void bbDisconnectOutput( const std::string& name,
283 /// @name Pipeline processing methods
284 /// Methods which participate to (forward or backward) pipeline processing.
285 /// 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).
286 /// The main method is bbBackwardUpdate which is called by bbExecute and implemented in UserBlackBox and ComplexBlackBox.
290 //==================================================================
291 /// Recursive pipeline processing in backward direction
292 /// (recursion is in backward direction however execution always goes forward).
293 /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
295 /// \returns The final status of the box (UPTODATE or MODIFIED)
296 /// \param caller : The connection which invoked the method; null if called by bbExecute
298 /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
300 /// - updates its inputs by calling bbUpdateInputs (which recursively calls bbBackwardUpdate on upstream boxes)
301 /// - calls bbCreateWidget
302 /// - calls bbProcess which is the user callback which does the actual processing
303 /// - calls bbUpdateChildren
304 /// - calls bbShowWidget which shows the widget associated to the box (if any)
306 virtual IOStatus bbBackwardUpdate(Connection::Pointer caller) = 0;
307 //==================================================================
309 //==================================================================
310 /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
311 /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
313 /// \param caller : The connection which invoked the method
315 /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
317 /// - calls bbCreateWidget
318 /// - calls bbProcess which is the user callback which does the actual processing
319 /// - calls bbUpdateChildren which recursively calls bbForwardUpdate on connections attached the "Child" output
320 // virtual void bbForwardUpdate(Connection::Pointer caller) = 0;
321 //==================================================================
323 //==================================================================
324 /// Updates the BlackBox inputs and returns the final status of the inputs
325 /// (==UPTODATE iff all inputs are UPTODATE)
326 // If excludeParent == true then excludes the upstream box connected to input 'Parent' from recursive update
327 IOStatus bbUpdateInputs(bool excludeParent=false);
328 //==================================================================
330 //==================================================================
331 /// Updates the pipeline in upstream-downstream direction along the "Child"-"Parent" connections only.
332 /// Does nothing here. Overloaded in WxContainerBlackbox
333 //virtual void bbUpdateChildren( Connection::Pointer caller ) { }
334 //==================================================================
336 //==================================================================
337 /// Specific methods for window creation during pipeline execution
338 /// Creates the window associated to the box (called after bbUpdateInputs)
339 /// Does nothing here. Overloaded in WxBlackBox.
340 // virtual void bbCreateWindow() { }
341 /// Shows the window associated to the box
342 /// (called after bbProcess during bbExecute)
343 /// Does nothing here but overloaded in WxBlackBox and WxContainerBlackBox
344 virtual void bbShowWindow(Connection::Pointer caller) { }
346 virtual void bbHideWindow() {}
347 virtual void bbCloseWindow() { }
348 //==================================================================
353 static bool bbGlobalGetSomeBoxExecuting();
354 static void bbGlobalSetSomeBoxExecuting(bool b);
356 static void bbGlobalSetFreezeExecution(bool b);
357 static bool bbGlobalGetFreezeExecution();
359 /// Returns true if the box can "react",
360 /// which means execute in response to an input change
361 virtual bool bbCanReact() const;
364 static void bbGlobalAddToExecutionList( BlackBox::Pointer b );
365 static void bbGlobalProcessExecutionList();
367 //==================================================================
369 //==================================================================
370 /// Allocates the i/o connectors of the black box
371 virtual void bbAllocateConnectors();
372 /// Desallocates the i/o connectors of the black box
373 virtual void bbDesallocateConnectors();
374 /// Copies the values of the inputs/output from the BlackBox from
375 virtual void bbCopyIOValues(BlackBox& from);
376 //==================================================================
378 // Black box objects have a special deleter
379 // which must take care of releasing the descriptor
380 // **AFTER** the box is deleted
381 // (Releasing it in the destructor may cause dl close and crash)
382 /// Black box deleter
383 /// 1) Calls the user overloadable bbDelete method
384 /// 2) Releases the box descriptor
385 struct BBTK_EXPORT Deleter : public Object::Deleter
388 void Delete(Object* p);
392 static boost::shared_ptr<U> MakeBlackBoxPointer(U* s, bool lock = false)
394 return MakePointer(s,BlackBox::Deleter(),lock);
397 virtual void bbDelete() { delete this; }
401 //==================================================================
403 /// The status of the box
405 /// The name of the black-box
407 /// The name of the package to which it belongs
408 std::string bbmPackageName;
410 /// 0 : "Pipeline" mode : bbBackwardUpdate() only calls Process if Status == MODIFIED (normal pipeline processing)
411 /// 1 : "Always" mode : bbUpdate() always calls Process
412 /// 2 : "Reactive" mode : bbSetModifiedStatus() calls bbUpdate()
413 std::string bbmBoxProcessMode;
415 /// The parent of the black box in the ComplexBlackBox hierarchy
416 BlackBox::WeakPointer bbmParent;
417 //==================================================================
420 //==================================================================
422 /// Map that contains the output connectors of the black box
423 OutputConnectorMapType mOutputConnectorMap;
424 /// Map that contains the input connectors of the black box
425 InputConnectorMapType mInputConnectorMap;
426 //==================================================================