]> 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/06/19 09:46:41 $
7   Version:   $Revision: 1.11 $
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 "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   class Connection;
47
48   class BBTK_EXPORT BlackBox : public Object
49   {
50     BBTK_ABSTRACT_OBJECT_INTERFACE(BlackBox);
51   public: 
52     //==================================================================
53     // INTERFACE
54     //==================================================================
55  
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;
62
63     /// Returns the pointer on the descriptor of the box
64     virtual BlackBoxDescriptor::Pointer bbGetDescriptor() const = 0;
65
66     /// Returns a pointer on a clone of the box with name <name>
67     virtual BlackBox::Pointer bbClone(const std::string& name) = 0;
68
69     /// User overloadable destruction method of a black box
70     virtual void bbUserDelete();
71
72     /// Returns the Name of the Type of the BlackBox
73     const std::string& bbGetTypeName() const 
74       { return bbGetDescriptor()->GetTypeName(); }
75  
76     
77     /// Returns the name of the BlackBox (instance)
78     const std::string& bbGetName() const { return bbmName; }
79
80     /// Returns the full name of the BlackBox (instance+type)
81     virtual std::string bbGetFullName() const;
82
83     /// Returns the name with the name of the parent prepended if any
84     virtual std::string bbGetNameWithParent() const;
85     
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(); }
88
89
90     /// Main processing method of the box.
91     virtual void bbExecute(bool force = false);
92
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);
117
118     /// Gets the status of the box
119     virtual const IOStatus& bbGetStatus() const { return bbmStatus; }
120
121
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;
126
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;
131
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;
136
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, 
142                                               void* data, 
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;
146
147
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; }      
160  
161
162     /// Prints the Help on the BlackBox type 
163     virtual void bbGetHelp(bool full=true) const;
164
165
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; }
172     typedef enum
173       {
174         Pipeline,
175         Always,
176         Reactive
177       }
178       BoxProcessModeValue;
179     /// Returns the "decoded" value of the input "BoxProcessMode"
180     BoxProcessModeValue bbGetBoxProcessModeValue() const;
181   
182     virtual bool bbBoxProcessModeIsReactive() const;
183
184     virtual bool bbBoxProcessModeIsAlways() const;
185
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) {}
190
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(); }
195
196     //==================================================================    
197
198
199     //==================================================================    
200
201     /// Does nothing here : overloaded in ComplexBlackBox
202     void bbInsertHTMLGraph(  std::ofstream& s, 
203                              int detail, 
204                              int level,
205                              bool instanceOrtype,
206                              const std::string& output_dir,
207                              bool relative_link ) 
208     {}
209
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, 
221                                         bool instanceOrtype,
222                                         bool relative_link );
223     /// Auxiliary method for bbWriteDotFileBlackBox
224     virtual void bbWriteDotInputOutputName(FILE *ff,
225                                            bool inputoutput, 
226                                            int detail, int level);
227     
228      
229     virtual void bbShowRelations(BlackBox::Pointer parentblackbox, 
230                                  int detail, int level
231                                  );
232     
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();}
237
238     virtual void Check(bool recursive = true);
239
240         virtual void bbUserOnShow() { }
241         void bbUserOnShowWidget(std::string nameInput);
242
243
244   protected:
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     //==================================================================
253
254
255     //==================================================================
256     ///  Sets the status of the box
257     void bbSetStatus( IOStatus t) { bbmStatus = t; } 
258     //==================================================================
259     
260   private:
261     friend class Connection;
262     friend class ComplexBlackBox;
263
264     /// Sets the parent of the BlackBox
265     void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
266     
267
268     /// Connects the input <name> to the connection c
269     virtual void bbConnectInput( const std::string& name, 
270                                  Connection* c);
271     /// Connects the output <name> to the connection c
272     virtual void bbConnectOutput( const std::string& name, 
273                                   Connection* c);
274     /// Disconnects the input <name> from the connection c
275     virtual void bbDisconnectInput( const std::string& name, 
276                                     Connection* c);
277     /// Disconnects the output <name> from the connection c
278     virtual void bbDisconnectOutput( const std::string& name, 
279                                      Connection* c);
280
281
282  
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.
287     /// 
288     //@{
289
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
294     /// 
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
297     ///
298     /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
299     /// then : 
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)
305   protected:
306     virtual IOStatus bbBackwardUpdate(Connection::Pointer caller) = 0;
307     //==================================================================
308
309     //==================================================================
310     /// Recursive pipeline processing in forward direction along "Child"-"Parent" connections
311     /// Pure virtual; defined in UserBlackBox and ComplexBlackBox
312     /// 
313     /// \param caller : The connection which invoked the method
314     ///
315     /// First checks that re-processing is needed (either Status==MODIFIED or InputProcessMode==Always)
316     /// then : 
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     //==================================================================
322   protected:
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     //==================================================================
329
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     //==================================================================
335
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) { }
345
346     virtual void bbHideWindow() {}
347     virtual void bbCloseWindow() { }
348    //==================================================================
349
350     //@}
351   public: 
352
353     static bool bbGlobalGetSomeBoxExecuting();
354     static void bbGlobalSetSomeBoxExecuting(bool b);
355
356     static void bbGlobalSetFreezeExecution(bool b);
357     static bool bbGlobalGetFreezeExecution();
358
359     /// Returns true if the box can "react",
360     /// which means execute in response to an input change 
361     virtual bool bbCanReact() const;
362     
363   protected:  
364     static void bbGlobalAddToExecutionList( BlackBox::Pointer b );
365     static void bbGlobalProcessExecutionList();
366
367     //==================================================================
368   protected:
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     //==================================================================
377
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
386     { 
387       Deleter();
388       void Delete(Object* p);
389     };
390
391     template <class U>
392     static boost::shared_ptr<U> MakeBlackBoxPointer(U* s, bool lock = false)
393     {
394       return MakePointer(s,BlackBox::Deleter(),lock);
395     }
396
397     virtual void bbDelete() { delete this; }
398   private:
399     
400  
401     //==================================================================
402     // PRIVATE PART 
403     /// The status of the box
404     IOStatus bbmStatus;
405     /// The name of the black-box
406     std::string bbmName;
407     /// The name of the package to which it belongs
408     std::string bbmPackageName;
409         
410     /// 0 : "Pipeline" mode : bbUpdate() 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;
414
415     /// The parent of the black box in the ComplexBlackBox hierarchy
416     BlackBox::WeakPointer bbmParent;
417     //==================================================================
418
419
420    //==================================================================
421     // ATTRIBUTES
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     //==================================================================
427
428
429  };
430   // Class BlackBox
431
432
433
434
435
436
437
438  
439 }
440 // namespace bbtk
441 #endif
442