]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.h
*** empty log message ***
[bbtk.git] / kernel / src / bbtkBlackBox.h
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkBlackBox.h,v $
5   Language:  C++
6   Date:      $Date: 2008/04/08 06:59:29 $
7   Version:   $Revision: 1.4 $
8                                                                                 
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.
12                                                                                 
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.
16                                                                                 
17 =========================================================================*/
18
19
20 /**
21  *  \file 
22  *  \brief Class bbtk::BlackBox : abstract black-box interface. 
23  */
24
25 /**
26  * \class bbtk::BlackBox
27  * \brief Abstract black-box interface 
28  */
29  
30 #ifndef __bbtkBlackBox_h__
31 #define __bbtkBlackBox_h__
32
33 #include "bbtkSystem.h"
34 #include "bbtkBlackBoxDescriptor.h"
35 //#include "bbtkConnection.h"
36 #include "bbtkBlackBoxInputConnector.h"
37 #include "bbtkBlackBoxOutputConnector.h"
38 #include <set>
39
40 namespace bbtk
41 {
42
43   
44   struct Void { Void(int = 0) {} };
45   
46   class Factory;
47
48   class BBTK_EXPORT BlackBox 
49   {
50
51
52   public: 
53     //==================================================================
54     // INTERFACE
55     //==================================================================
56     /// The type of pointer on a BlackBox
57     typedef BlackBox* Pointer;
58
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;
65
66     /// Returns the pointer on the descriptor of the box
67     virtual BlackBoxDescriptor* bbGetDescriptor() const = 0;
68
69     /// Returns a pointer on a clone of the box with name <name>
70     virtual BlackBox* bbClone(const std::string& name) = 0;
71
72     /// Destruction method of a black box
73     virtual void bbDelete();
74     /// User overloadable destruction method of a black box
75     virtual void bbUserDelete();
76
77     /// Returns the Name of the Type of the BlackBox
78     const std::string& bbGetTypeName() const 
79       { return bbGetDescriptor()->GetTypeName(); }
80  
81     
82     /// Returns the name of the BlackBox (instance)
83     const std::string& bbGetName() const { return bbmName; }
84
85     /// Returns the full name of the BlackBox (instance+type)
86     virtual std::string bbGetFullName() const;
87
88     /// Returns the name with the name of the parent prepended if any
89     std::string bbGetNameWithParent() const;
90     
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; }
95
96
97     /// Main processing method of the box.
98     virtual void bbExecute(bool force = false);
99
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);
124
125     /// Gets the status of the box
126     virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
127
128
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;
133
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;
138
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;
143
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, 
149                                               void* data, 
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;
153
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);
158
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);
163
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; }      
176  
177
178     /// Prints the Help on the BlackBox type 
179     virtual void bbGetHelp(bool full=true) const;
180
181
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; }
188     typedef enum
189       {
190         Pipeline,
191         Always,
192         Reactive
193       }
194       BoxProcessModeValue;
195     /// Returns the "decoded" value of the input "BoxProcessMode"
196     BoxProcessModeValue bbGetBoxProcessModeValue() const;
197   
198     virtual bool bbBoxProcessModeIsReactive() const;
199
200     virtual bool bbBoxProcessModeIsAlways() const;
201
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) {}
206
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(); }
211
212     //==================================================================    
213
214
215     //==================================================================    
216
217     /// Does nothing here : overloaded in ComplexBlackBox
218     void bbInsertHTMLGraph(  std::ofstream& s, 
219                              int detail, 
220                              int level,
221                              bool instanceOrtype,
222                              const std::string& output_dir,
223                              bool relative_link ) 
224     {}
225
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, 
237                                         bool instanceOrtype,
238                                         bool relative_link );
239     /// Auxiliary method for bbWriteDotFileBlackBox
240     virtual void bbWriteDotInputOutputName(FILE *ff,
241                                            bool inputoutput, 
242                                            int detail, int level);
243     
244      
245     virtual void bbShowRelations(BlackBox *parentblackbox, 
246                                  int detail, int level
247                                  );
248     
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;}
252
253   protected:
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);
261     ///  Destructor
262     virtual ~BlackBox();
263     //==================================================================
264
265
266     //==================================================================
267     ///  Sets the status of the box
268     void bbSetStatus( IOStatus t) { bbmStatus = t; } 
269     //==================================================================
270     
271
272  
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.
277     /// 
278     //@{
279
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
284     /// 
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
287     ///
288     /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
289     /// then : 
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)
295   public:
296     virtual IOStatus bbBackwardUpdate(Connection* caller) = 0;
297     //==================================================================
298
299     //==================================================================
300     /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
301     /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
302     /// 
303     /// \param caller : The connection which invoked the method
304     ///
305     /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
306     /// then : 
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     //==================================================================
312   protected:
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     //==================================================================
319
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     //==================================================================
325
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) { }
335  
336     virtual void bbHideWindow() {}
337    //==================================================================
338
339     //@}
340   public: 
341
342     static bool bbGlobalGetSomeBoxExecuting();
343     static void bbGlobalSetSomeBoxExecuting(bool b);
344
345     static void bbGlobalSetFreezeExecution(bool b);
346     static bool bbGlobalGetFreezeExecution();
347
348     /// Returns true if the box can "react",
349     /// which means execute in response to an input change 
350     virtual bool bbCanReact() const;
351     
352     
353     static void bbGlobalAddToExecutionList( BlackBox* b );
354     static void bbGlobalProcessExecutionList();
355
356     //==================================================================
357   protected:
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     //==================================================================
366
367     bool bbGetExecuting() const { return bbmExecuting; }
368     void bbSetExecuting(bool b) { bbmExecuting = b; }
369
370   private:
371     
372  
373     //==================================================================
374     // PRIVATE PART 
375     /// Default constructor is private : derived classes must use the constructor with the BlackBox's name
376     BlackBox() {}
377     /// The status of the box
378     IOStatus bbmStatus;
379     /// The name of the black-box
380     std::string bbmName;
381     /// The name of the package to which it belongs
382     std::string bbmPackageName;
383         
384     /// 0 : "Pipeline" mode : bbUpdate() only calls Process if Status == MODIFIED (normal pipeline processing)
385     /// 1 : "Always" mode : bbUpdate() always calls Process  
386     /// 2 : "Reactive" mode : bbSetModifiedStatus() calls bbUpdate()
387     std::string bbmBoxProcessMode;
388
389     /// The parent of the black box in the ComplexBlackBox hierarchy
390     BlackBox::Pointer bbmParent;
391     //==================================================================
392
393     //==================================================================
394     // Am I executing (to test pipeline cycles) ?
395     bool bbmExecuting;
396     //==================================================================
397
398    //==================================================================
399     // ATTRIBUTES
400     ///  Map that contains the output connectors of the black box
401     OutputConnectorMapType mOutputConnectorMap; 
402     ///  Map that contains the input connectors of the black box
403     InputConnectorMapType mInputConnectorMap;
404     //==================================================================
405
406
407  };
408   // Class BlackBox
409
410
411
412
413
414
415
416  
417 }
418 // namespace bbtk
419 #endif
420