]> 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/01/22 15:02:00 $
7   Version:   $Revision: 1.1 $
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 "bbtkBlackBoxDescriptor.h"
34 //#include "bbtkConnection.h"
35 #include "bbtkBlackBoxInputConnector.h"
36 #include "bbtkBlackBoxOutputConnector.h"
37 #include <set>
38
39 namespace bbtk
40 {
41
42   
43   struct Void { Void(int = 0) {} };
44   
45   class Factory;
46
47   class BBTK_EXPORT BlackBox 
48   {
49
50
51   public: 
52     //==================================================================
53     // INTERFACE
54     //==================================================================
55     /// The type of pointer on a BlackBox
56     typedef BlackBox* Pointer;
57
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;
64
65     /// Returns the pointer on the descriptor of the box
66     virtual BlackBoxDescriptor* bbGetDescriptor() const = 0;
67
68     /// Returns a pointer on a clone of the box with name <name>
69     virtual BlackBox* bbClone(const std::string& name) = 0;
70
71     /// Destruction method of a black box
72     virtual void bbDelete();
73     /// User overloadable destruction method of a black box
74     virtual void bbUserDelete();
75
76     /// Returns the Name of the Type of the BlackBox
77     const std::string& bbGetTypeName() const 
78       { return bbGetDescriptor()->GetTypeName(); }
79  
80     
81     /// Returns the name of the BlackBox (instance)
82     const std::string& bbGetName() const { return bbmName; }
83
84     /// Returns the full name of the BlackBox (instance+type)
85     virtual std::string bbGetFullName() const;
86
87     /// Returns the name with the name of the parent prepended if any
88     std::string bbGetNameWithParent() const;
89     
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; }
94
95
96     /// Main processing method of the box.
97     virtual void bbExecute(bool force = false);
98
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);
123
124     /// Gets the status of the box
125     virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
126
127
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;
132
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;
137
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;
142
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, 
148                                               void* data, 
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;
152
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);
157
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);
162
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; }      
175  
176
177     /// Prints the Help on the BlackBox type 
178     virtual void bbGetHelp(bool full=true) const;
179
180
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; }
187     typedef enum
188       {
189         Pipeline,
190         Always,
191         Reactive
192       }
193       BoxProcessModeValue;
194     /// Returns the "decoded" value of the input "BoxProcessMode"
195     BoxProcessModeValue bbGetBoxProcessModeValue() const;
196   
197     virtual bool bbBoxProcessModeIsReactive() const;
198
199     virtual bool bbBoxProcessModeIsAlways() const;
200
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) {}
205
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(); }
210
211     //==================================================================    
212
213
214     //==================================================================    
215
216     /// Does nothing here : overloaded in ComplexBlackBox
217     void bbInsertHTMLGraph(  std::ofstream& s, 
218                              int detail, 
219                              int level,
220                              bool instanceOrtype,
221                              const std::string& output_dir,
222                              bool relative_link ) 
223     {}
224
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, 
236                                         bool instanceOrtype,
237                                         bool relative_link );
238     /// Auxiliary method for bbWriteDotFileBlackBox
239     virtual void bbWriteDotInputOutputName(FILE *ff,
240                                            bool inputoutput, 
241                                            int detail, int level);
242     
243      
244     virtual void bbShowRelations(BlackBox *parentblackbox, 
245                                  int detail, int level
246                                  );
247     
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;}
251
252   protected:
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);
260     ///  Destructor
261     virtual ~BlackBox();
262     //==================================================================
263
264
265     //==================================================================
266     ///  Sets the status of the box
267     void bbSetStatus( IOStatus t) { bbmStatus = t; } 
268     //==================================================================
269     
270
271  
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.
276     /// 
277     //@{
278
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
283     /// 
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
286     ///
287     /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
288     /// then : 
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)
294   public:
295     virtual IOStatus bbBackwardUpdate(Connection* caller) = 0;
296     //==================================================================
297
298     //==================================================================
299     /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
300     /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
301     /// 
302     /// \param caller : The connection which invoked the method
303     ///
304     /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
305     /// then : 
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     //==================================================================
311   protected:
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     //==================================================================
318
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     //==================================================================
324
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) { }
334  
335     virtual void bbHideWindow() {}
336    //==================================================================
337
338     //@}
339   public: 
340
341     static bool bbGlobalGetSomeBoxExecuting() 
342     { return bbmgSomeBoxExecuting; }
343     static void bbGlobalSetSomeBoxExecuting(bool b) 
344     { bbmgSomeBoxExecuting = b; }
345
346
347     static void bbGlobalSetFreezeExecution(bool b) { bbmgFreezeExecution = b;}
348     static bool bbGlobalGetFreezeExecution() { return bbmgFreezeExecution; }
349
350     /// Returns true if the box can "react",
351     /// which means execute in response to an input change 
352     virtual bool bbCanReact() const;
353     
354     
355     static void bbGlobalAddToExecutionList( BlackBox* b ) 
356    { 
357      bbmgExecutionList.insert(b);   
358
359
360     static void bbGlobalProcessExecutionList();
361
362     //==================================================================
363   protected:
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     //==================================================================
372
373   private:
374     
375  
376     //==================================================================
377     // PRIVATE PART 
378     /// Default constructor is private : derived classes must use the constructor with the BlackBox's name
379     BlackBox() {}
380     /// The status of the box
381     IOStatus bbmStatus;
382     /// The name of the black-box
383     std::string bbmName;
384     /// The name of the package to which it belongs
385     std::string bbmPackageName;
386         
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;
391
392     /// The parent of the black box in the ComplexBlackBox hierarchy
393     BlackBox::Pointer bbmParent;
394     //==================================================================
395
396    //==================================================================
397     // ATTRIBUTES
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     //==================================================================
403
404     
405     static bool bbmgSomeBoxExecuting;
406     static bool bbmgFreezeExecution;
407
408
409    static std::set<BlackBox*> bbmgExecutionList;
410  };
411   // Class BlackBox
412
413
414
415
416
417
418
419  
420 }
421 // namespace bbtk
422 #endif
423