]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.h
#3005 BBTK Feature New Normal - TypeName in message system BlackBox
[bbtk.git] / kernel / src / bbtkBlackBox.h
1 /*
2  # ---------------------------------------------------------------------
3  #
4  # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5  #                        pour la SantÈ)
6  # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7  # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8  # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9  #
10  #  This software is governed by the CeCILL-B license under French law and
11  #  abiding by the rules of distribution of free software. You can  use,
12  #  modify and/ or redistribute the software under the terms of the CeCILL-B
13  #  license as circulated by CEA, CNRS and INRIA at the following URL
14  #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15  #  or in the file LICENSE.txt.
16  #
17  #  As a counterpart to the access to the source code and  rights to copy,
18  #  modify and redistribute granted by the license, users are provided only
19  #  with a limited warranty  and the software's author,  the holder of the
20  #  economic rights,  and the successive licensors  have only  limited
21  #  liability.
22  #
23  #  The fact that you are presently reading this means that you have had
24  #  knowledge of the CeCILL-B license and that you accept its terms.
25  # ------------------------------------------------------------------------ */
26
27
28 /*=========================================================================
29   Program:   bbtk
30   Module:    $RCSfile: bbtkBlackBox.h,v $
31   Language:  C++
32   Date:      $Date: 2012/11/16 08:49:01 $
33   Version:   $Revision: 1.34 $
34 =========================================================================*/
35
36
37
38 /**
39  *  \file
40  *  \brief Class bbtk::BlackBox : abstract black-box interface.
41  */
42
43 /**
44  * \class bbtk::BlackBox
45  * \brief Abstract black-box interface
46  */
47
48 #ifndef __bbtkBlackBox_h__
49 #define __bbtkBlackBox_h__
50
51 #include "bbtkSystem.h"
52 #include "bbtkMessageManager.h"
53 #include "bbtkBlackBoxDescriptor.h"
54 #include "bbtkBlackBoxInputConnector.h"
55 //#include "bbtkBlackBoxOutputConnector.h"
56 #include <set>
57
58 // Signal/slot mechanism for output change events
59 #include <boost/signals2/signal.hpp>
60 #include <boost/bind.hpp>
61
62
63 #define bbtkBlackBoxMessage(key,level,mess) \
64   bbtkMessage(key,level,"["<<bbGetTypeName()<<":"<<bbGetName()<<"] "<<mess)
65 #define bbtkBlackBoxDebugMessage(key,level,mess)        \
66   bbtkDebugMessage(key,level,"["<<bbGetTypeName()<<":"<<bbGetName()<<"] "<<mess)
67
68 namespace bbtk
69 {
70
71   struct Void { Void(int = 0) {} };
72
73   class Factory;
74   class Connection;
75   class BlackBoxOutputConnector;
76
77   class BBTK_EXPORT BlackBox : public Object
78   {
79     BBTK_ABSTRACT_OBJECT_INTERFACE(BlackBox);
80
81
82   public:
83
84     //==================================================================
85     // Types
86     //==================================================================
87     typedef boost::signals2::trackable OutputChangeObserverType;
88     typedef boost::signals2::signal<void (bbtk::BlackBox::Pointer,
89                                 const std::string&,
90                                 IOStatus)>  OutputChangeSignalType;
91     typedef OutputChangeSignalType::slot_function_type
92     OutputChangeCallbackType;
93
94     /// The type of map of output connector pointers
95     typedef std::map<std::string, BlackBoxOutputConnector*>
96     OutputConnectorMapType;
97     /// The type of map of input connector pointers
98     typedef std::map<std::string, BlackBoxInputConnector*>
99     InputConnectorMapType;
100     //==================================================================
101
102
103     //==================================================================
104     /// @name Pipeline processing methods
105     ///  Methods which participate to pipeline processing.
106     //@{
107     /// Main processing method of the box.
108     virtual void bbExecute(bool force = false);
109     //@}
110     //==================================================================
111
112
113
114
115
116     //==================================================================
117     /// Returns a pointer on a clone of the box with name <name>
118     virtual BlackBox::Pointer bbClone(const std::string& name) = 0;
119     //==================================================================
120
121
122    //==================================================================
123     /// @name General accessors
124     ///  Methods which give access to general informations on the box
125     //@{
126
127     /// Returns the pointer on the descriptor of the box
128     virtual BlackBoxDescriptor::Pointer bbGetDescriptor() const = 0;
129
130     /// Returns the Name of the Type of the BlackBox
131     const std::string& bbGetTypeName() const
132       { return bbGetDescriptor()->GetTypeName(); }
133
134
135     /// Returns the name of the BlackBox (instance)
136     const std::string& bbGetName() const { return bbmName; }
137
138     /// Returns the full name of the BlackBox (instance+type)
139     virtual std::string bbGetFullName() const;
140
141     /// Returns the name with the name of the parent prepended if any
142     virtual std::string bbGetNameWithParent() const;
143
144     /// Returns the parent of the BlackBox, i.e the BlackBox that contains it (0 if none)
145     BlackBox::Pointer bbGetParent() const { return bbmParent.lock(); }
146
147     //@}
148     //==================================================================
149
150
151
152     //==================================================================
153     /// @name Inputs/Outputs related methods
154     ///  Methods related to the box inputs and outputs
155     //@{
156
157     /// Returns true iff the BlackBox has an input of name label
158     virtual bool bbHasInput(const std::string& label) const;
159     ///  Gets the input type of a given label
160     virtual TypeInfo bbGetInputType( const std::string &label ) const;
161     /// Gets the status of the input called <name>
162     IOStatus bbGetInputStatus( const std::string &name ) const
163     { return mInputConnectorMap.find(name)->second->GetStatus(); }
164     ///  Gets the data of the input called <name>
165     virtual Data bbGetInput( const std::string &name )  = 0;
166     ///  Gets the data of the input called <name> as a string using an Adaptor if possible (else returns empty string)
167     std::string bbGetInputAsString( const std::string &input);
168
169
170    /// Sets the data of the input called <name>.
171     /// If update_time is false then does not update ChangeTime of input
172     virtual void bbSetInput( const std::string &name, Data data,
173                              bool update_time = true ) = 0;
174     /// [SYSTEM]: Sets the data of the input called <name> which **MUST* be a pointer
175     virtual void bbBruteForceSetInputPointer( const std::string &name,
176                                               void* data,
177                                               bool update_time = true) =0;
178
179
180     /// Returns true iff the BlackBox has an output of name label
181     virtual bool bbHasOutput(const std::string& label) const;
182     ///  Gets the output type of a given label
183     virtual TypeInfo bbGetOutputType( const std::string &label ) const;
184     ///  Gets the data of the output called <name>
185     virtual Data bbGetOutput( const std::string &name ) = 0;
186     ///  Gets the data of the output called <name> as a string using an Adaptor if possible (else returns empty string)
187     std::string bbGetOutputAsString( const std::string &output ); //,Factory *factory);
188
189     ///  Sets the data of the output called <name>
190     virtual void bbSetOutput( const std::string &name, Data data) = 0;
191
192
193     ///  Returns the input connectors map
194     InputConnectorMapType&  bbGetInputConnectorMap()
195     { return mInputConnectorMap; }
196     ///  Returns the input connectors map (const)
197     const InputConnectorMapType&  bbGetInputConnectorMap() const
198     { return mInputConnectorMap; }
199    ///  Returns the input connector
200     BlackBoxInputConnector&  bbGetInputConnector(const std::string& n)
201     { return *(mInputConnectorMap.find(n)->second); }
202     ///  Returns the input connector (const)
203     const BlackBoxInputConnector&  bbGetInputConnector(const std::string& n) const
204     { return *(mInputConnectorMap.find(n)->second); }
205
206
207     ///  Returns the output connectors map
208     OutputConnectorMapType& bbGetOutputConnectorMap()
209     { return mOutputConnectorMap; }
210     ///  Returns the output connectors map (const)
211     const OutputConnectorMapType& bbGetOutputConnectorMap() const
212     { return mOutputConnectorMap; }
213     ///  Returns the output connector
214     BlackBoxOutputConnector& bbGetOutputConnector(const std::string& n)
215     { return *(mOutputConnectorMap.find(n)->second); }
216      ///  Returns the output connector (const)
217     const BlackBoxOutputConnector& bbGetOutputConnector(const std::string& n) const
218     { return *(mOutputConnectorMap.find(n)->second); }
219
220     //@}
221     //==================================================================
222
223     /// Prints the Help on the BlackBox type
224     virtual void bbGetHelp(bool full=true) const;
225
226
227
228     //==================================================================
229     /// @name Output signals / observers related methods
230     ///  Methods related to signals emitted by outputs and the
231     //@{
232
233     //==================================================================
234     /// Adds the function f to the list of functions to call when
235     /// the output changes.
236     /// f is of type ChangeCallbackType which is basically:
237     /// void (*ChangeCallbackType)(bbtk::BlackBox::Pointer,
238     ///                            const std::string&,
239     ///                            bbtk::IOStatus)
240     /// To pass a member function 'f' of an instance 'c' of a class 'C'
241     /// as callback you have to 'bind' it, i.e. call:
242     /// bbAddOutputObserver ( "Out", boost::bind( &C::f , c, _1, _2, _3 ) );
243     /// The convenience macro BBTK_BIND_OUTPUT_OBSERVER ( c, C::f ) does it for you
244     void bbAddOutputObserver(const std::string& output_name,
245                              OutputChangeCallbackType f);
246
247     /// Removes the function f from the list of functions to call when
248     /// the output changes (TO WRITE)
249     void bbRemoveOutputObserver(const std::string& output_name,
250                                 OutputChangeCallbackType f);
251    //==================================================================
252
253
254     //==================================================================
255     /// Signals that the BlackBox outputs have been modified
256     /// (without marking the box as MODIFIED because its output state is ok : don't care if you understand : use it !).
257     /// This method should be used by widgets in response
258     /// to user interaction when **ALL** outputs have been modified
259     /// (after the outputs has been updated !).
260     /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
261     /// ** USER INTENDED **
262     virtual void bbSignalOutputModification(bool reaction = true);
263     /// Signals that the BlackBox output "output_name" has been modified
264     /// (without marking the box as MODIFIED because its output state is ok : don't care if you understand : use it !).
265     /// This method should be used by widgets in response to user interaction
266     /// only when **ONE** output has been modified
267     /// (after the output has been updated !)
268     /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
269     /// ** USER INTENDED **
270     virtual void bbSignalOutputModification( const std::string& output_name,
271                                              bool reaction = true);
272     /// Signals that the BlackBox vector of outputs "output_name"
273     /// have been modified.
274     /// Should be used when more than ONE output is modified but not ALL
275     /// (optimization issue).
276     /// (without marking the box as MODIFIED because its output state is ok).
277     /// This method should be used by widgets in response to user interaction
278     /// When more than one output has been changed but not all
279     /// (after the outputs have been updated of course!)
280     /// DO NOT PASS reaction = false OR WILL NOT WORK PROPERLY
281     /// ** USER INTENDED **
282     virtual void bbSignalOutputModification( const std::vector<std::string>&
283                                              output_name,
284                                              bool reaction = true);
285    //==================================================================
286     //@}
287
288
289
290
291
292
293     //==================================================================
294     /// @name Common inputs / outputs to all boxes
295     //@{
296     /// Returns the value of the input 'BoxProcessMode'
297     std::string bbGetInputBoxProcessMode() { return bbmBoxProcessMode; }
298     /// Sets the value of the input 'BoxProcessMode'
299     void bbSetInputBoxProcessMode(std::string a) { bbmBoxProcessMode = a; }
300     /// The possible values of the input 'BoxProcessMode'
301  
302     typedef enum 
303      {
304       bbPipeline,
305       bbAlways,
306       bbReactive,
307           bbManual
308      }
309     BoxProcessModeValue;
310     
311     /// Returns the "decoded" value of the input "BoxProcessMode"
312     BoxProcessModeValue bbGetBoxProcessModeValue() const;
313     /// Returns true iff the input 'BoxProcessMode' is set to 'Reactive' (or a synonym)
314     virtual bool bbBoxProcessModeIsReactive() const;
315     /// Returns true iff the input 'BoxProcessMode' is set to 'Always' (or a synonym)
316     virtual bool bbBoxProcessModeIsAlways() const;
317         /// Returns true iff the input 'BoxProcessMode' is set to 'Manual' (or a synonym)
318         virtual bool bbBoxProcessModeIsManual() const;
319
320     /// Returns the value of the input 'BoxExecute'
321     Void bbGetInputBoxExecute() { return Void(); }
322     /// Sets the value of the input 'BoxExecute'
323           void bbSetInputBoxExecute(Void = 0) {  }
324
325     /// Returns the value of the output 'BoxChange'
326     Void bbGetOutputBoxChange() { return Void(); }
327     /// Sets the value of the output 'BoxChange'
328     void bbSetOutputBoxChange(Void = 0) {  }
329     //@}
330     //==================================================================
331
332     virtual void bbPrintHelp(BlackBox::Pointer parentblackbox,
333                              int detail, int level
334                              );
335
336     /// Does nothing here : overloaded in ComplexBlackBox
337     void bbInsertHTMLGraph(  std::ofstream& s,
338                              int detail,
339                              int level,
340                              bool instanceOrtype,
341                              const std::string& output_dir,
342                              bool relative_link )
343     {}
344
345
346     //==================================================================
347     /// @name Window related methods
348     //@{
349     virtual void bbSetShown(bool) {}
350     virtual bool bbIsShown() { return false; }
351     //@}
352     //==================================================================
353
354     //JCP changed to public 09-06-09
355         //==================================================================
356             /// @name Manage the execution
357             //@{
358             static bool bbGlobalGetSomeBoxExecuting();
359             static void bbGlobalSetSomeBoxExecuting(bool b);
360
361             static void bbGlobalSetFreezeExecution(bool b);
362             static bool bbGlobalGetFreezeExecution();
363
364             static void bbGlobalAddToExecutionList( BlackBox::Pointer b );
365             static void bbGlobalProcessExecutionList();
366
367             //@}
368     //JCP 09-06-09
369
370   protected:
371
372    //==================================================================
373     /// @name User redefinable methods
374     ///  Virtual methods which can be redefined by inherited classes
375     //@{
376
377     //==================================================================
378     /// User can redefine this method to set
379     /// the default values of the box inputs and outputs
380     /// (it is called in the box constructor)
381     virtual void bbUserSetDefaultValues() {}
382
383     /// User can redefine this method to initialize what must be
384     /// initialized for the box to work, for example allocate dynamic data.
385     /// It is called once and only once before any call to bbUserCreateWidget
386     /// or bbUserProcess.
387     /// What has been allocated here must be desalocated in
388     /// bbFinalizeProcessing
389     virtual void bbUserInitializeProcessing() {}
390
391     /// User must redefine this method to uninitialize what has been
392     /// initialized in bbUserInitializeProcessing,
393     /// typically desallocate memory that has been allocated dynamically.
394     /// It is called in the box destructor if and only if (iff)
395     /// bbUserInitializeProcessing has been called previously.
396     virtual void bbUserFinalizeProcessing() {}
397     ///
398     virtual void bbUserOnShow() {}
399
400     //==================================================================
401     // @}
402     //==================================================================
403
404
405     //==================================================================
406
407     /// Write Graphviz-dot description in file.
408     /// Here dumps a single box description (i/o) but overloaded
409     /// in ComplexBlackBox to dump the internal pipeline representation
410     /// recursing into internal boxes descriptions if level>0.
411     /// detail = 1 : draw inputs and outputs (do not draw otherwise)
412     /// instanceOrtype = true : draw inputs and outputs VALUES
413     ///  (uses bbGetInputAsString / bbGetOutputAsString which use adaptors)
414     /// If relative_link is true then creates relative hrefs
415     virtual void bbWriteDotFileBlackBox(FILE *ff,
416                                         BlackBox::Pointer parentblackbox,
417                                         int detail, int level,
418                                         bool instanceOrtype,
419                                         bool relative_link );
420     /// Auxiliary method for bbWriteDotFileBlackBox
421     virtual void bbWriteDotInputOutputName(FILE *ff,
422                                            bool inputoutput,
423                                            int detail, int level);
424
425      virtual BlackBox::Pointer bbFindBlackBox(const std::string &blackboxname)
426               { return BlackBox::Pointer();}
427
428     virtual void Check(bool recursive = true);
429
430     //==================================================================
431     // PROTECTED PART : ACCESSIBLE TO THE BlackBox DEVELOPER
432     // (IN INHERITED CLASSES)
433     /// Constructor that take the BlackBox's name
434     BlackBox(const std::string &name);
435     /// Constructor from an existing box (copy) with a new name
436     BlackBox(BlackBox& from, const std::string &name);
437     //==================================================================
438
439
440
441     //==================================================================
442     /// @name Pipeline processing methods
443     ///  Methods which participate to pipeline processing.
444     //@{
445     //==================================================================
446     /// Recursive execution method
447     ///
448     /// \param caller : The connection which invoked the method; null if called by bbExecute
449     virtual void bbRecursiveExecute(Connection::Pointer caller);
450     //==================================================================
451
452     //==================================================================
453     /// Updates the BlackBox inputs
454     /// Calls RecursiveExecute on all BlackBoxInputConnector
455     /// \returns The maximum of final IOStatus after each input update
456     IOStatus bbUpdateInputs();
457     //==================================================================
458
459
460     //==================================================================
461     /// Actual CreateWindow method (vitual)
462     /// Overloaded in AtomicBlacBox and descendants
463     virtual void bbCreateWindow()
464     {
465       //  bbtkError("BlackBox::bbCreateWidget called : how can this happen ?");
466     }
467     //==================================================================
468
469     //==================================================================
470     /// Actual ShowWindow method (vitual)
471     /// Overloaded in AtomicBlacBox and descendants
472     virtual void bbShowWindow()
473     {
474       //  bbtkError("BlackBox::bbShowWidget called : how can this happen ?");
475     }
476     //==================================================================
477
478
479    //==================================================================
480     /// Actual processing method (vitual)
481     /// Overloaded in AtomicBlacBox and descendants
482     virtual void bbProcess()
483     {
484       bbtkError("BlackBox::bbProcess called : how can this happen ?");
485 //      this->bbUserProcess();
486     }
487     //==================================================================
488
489     //==================================================================
490     /// Computes the final IOStatus of inputs and outputs after processing
491 virtual    void bbComputePostProcessStatus();
492     //@}
493     //==================================================================
494
495
496     //==================================================================
497     /// Signals that the input whose connector is c has changed
498     /// and propagates the info downward
499     /// ** NOT USER INTENDED **
500     virtual void bbSetStatusAndPropagate(BlackBoxInputConnector* c,
501                                          IOStatus s);
502     //==================================================================
503
504
505
506     //==================================================================
507     /// @name Box con(des)struction / initi(fin)alization methods
508     //@{
509
510     //==================================================================
511     /// Allocates the i/o connectors of the black box
512     virtual void bbAllocateConnectors();
513     /// Desallocates the i/o connectors of the black box
514     virtual void bbDesallocateConnectors();
515     /// Copies the values of the inputs/output from the BlackBox from
516     virtual void bbCopyIOValues(BlackBox& from);
517     //==================================================================
518
519     //==================================================================
520     /// Initializes processing IF NEEDED.
521     /// Calls bbRecursiveInitializeProcessing if the box is in
522     /// "uninitialized" state and put it in "initialized" state.
523     /// On construction, boxes are "uninitialized".
524     /// See also bbFinalizeProcessing
525     void bbInitializeProcessing();
526
527     /// Finalizes processing IF NEEDED.
528     /// Calls bbRecursiveFinalizeProcessing if the box is in
529     /// "initialized" state and put it in "uninitialized" state.
530     /// On construction, boxes are "uninitialized".
531     /// See also bbInitializeProcessing
532     void bbFinalizeProcessing();
533
534     /// Abstract prototype of the method which
535     /// Recursively calls itself for the parent black box and then
536     /// calls bbUserInitializeProcessing for its own class.
537     /// It is redefined in each black box descendant.
538     /// Allows to call bbUserInitializeProcessing for all inherited classes
539     /// (like a constructor does)
540     virtual void bbRecursiveInitializeProcessing() {}
541
542
543     /// Abstract prototype of the method which
544     /// calls bbUserFinalizeProcessing for its own class and then
545     /// recursively calls itself for the parent black box.
546     /// It is redefined in each black box descendant.
547     /// Allows to call bbUserFinalizeProcessing for all inherited classes
548     /// (like a destructor does)
549     virtual void bbRecursiveFinalizeProcessing() {}
550     //==================================================================
551
552     //@}
553     //==================================================================
554
555   private:
556     //==================================================================
557     friend class Connection;
558     friend class ComplexBlackBox;
559
560     /// Sets the parent of the BlackBox
561     void bbSetParent(BlackBox::Pointer p) { bbmParent = p; }
562
563     //==================================================================
564     /// @name Input/output connection/disconnection
565     /// INTERNAL METHODS used by a Connection to connect/disconnect
566     /// itself to the i/o connectors of the box
567     //@{
568
569     /// Connects the input <name> to the connection c
570     virtual void bbConnectInput( const std::string& name, Connection* c);
571     /// Connects the output <name> to the connection c
572     virtual void bbConnectOutput( const std::string& name, Connection* c);
573     /// Disconnects the input <name> from the connection c
574     virtual void bbDisconnectInput( const std::string& name, Connection* c);
575     /// Disconnects the output <name> from the connection c
576     virtual void bbDisconnectOutput( const std::string& name, Connection* c);
577     //@}
578     //==================================================================
579
580     /// Returns true if the box can "react",
581     /// which means execute in response to an input change
582     virtual bool bbCanReact() const;
583
584     /// Returns true iff the box is executing
585     bool bbGetExecuting() const { return bbmExecuting; }
586     /// Sets the bbmExecuting bool returned by bbGetExecuting
587     void bbSetExecuting(bool b) { bbmExecuting = b; }
588
589     //==================================================================
590   protected:
591
592
593      //==================================================================
594     /// Black box objects have a special deleter
595     /// which must take care of releasing the descriptor
596     /// **AFTER** the box is deleted
597     /// (Releasing it in the destructor may cause dl close and crash)
598     /// Black box deleter
599     /// 1) Calls the user overloadable bbDelete method
600     /// 2) Releases the box descriptor
601     struct BBTK_EXPORT Deleter : public Object::Deleter
602     {
603       Deleter();
604       int Delete(Object* p);
605     };
606     //==================================================================
607
608     //==================================================================
609     /// Like Object::MakePointer but returns a boost::shared_pointer which uses a BlackBox::Deleter to delete the object instead of the default Object::Deleter
610     template <class U>
611     static boost::shared_ptr<U> MakeBlackBoxPointer(U* s, bool lock = false)
612     {
613       return MakePointer(s,BlackBox::Deleter(),lock);
614     }
615     //==================================================================
616
617     //==================================================================
618     /// Effective deletion method called by the Deleter.
619     /// The default implementation is to issue 'delete this'
620     /// but it can be redefined in inherited classes to handle special deletion mechanisms (e.g. ref counting, private destructors, such as vtk objects deletion with method Delete, etc.).
621     /// \return The number of remaining references on the object after the call (if meaningfull...): used by bbtk to warn a user if another smart pointing system is still holding the object...
622
623 //JCP 21-09-20 09 delete this throws and exception change due to compiler version changing and boost version
624     virtual int bbDelete() { delete this; 
625                              return 0; }
626     //==================================================================
627
628
629     //==================================================================
630   private:
631     //==================================================================
632
633     //==================================================================
634     // ATTRIBUTES
635     /// Is the box initialized ?
636     bool bbmInitialized;
637     /// Is the box executing ?
638     bool bbmExecuting;
639     /// The name of the black-box
640     std::string bbmName;
641     /// The name of the package to which it belongs
642     std::string bbmPackageName;
643     /// The box processing mode
644     /// 0 : "Pipeline" mode
645     /// 1 : "Always" mode
646     /// 2 : "Reactive" mode
647         /// 3 : "Manual" mode
648     std::string bbmBoxProcessMode;
649     /// The parent of the black box in the ComplexBlackBox hierarchy
650     BlackBox::WeakPointer bbmParent;
651     //==================================================================
652
653
654    //==================================================================
655     // ATTRIBUTES
656     ///  Map that contains the output connectors of the black box
657     OutputConnectorMapType mOutputConnectorMap;
658     ///  Map that contains the input connectors of the black box
659     InputConnectorMapType mInputConnectorMap;
660     //==================================================================
661           
662           
663           bool bbLetRecursiveExecuteManualMode;
664  };
665   // Class BlackBox
666
667
668   /// Convenient macro to create output observer callbacks (freehand functions) from object and method pointer (see samples/SampleOutputObserver)
669 #define BBTK_MAKE_OUTPUT_OBSERVER(OBJECT,METHOD) \
670     boost::bind( METHOD, OBJECT, _1, _2, _3)
671
672 }
673 // namespace bbtk
674 #endif