]> Creatis software - bbtk.git/blob - kernel/src/bbtkComplexBlackBoxDescriptor.cxx
2cc69bb7e94992195d944f7a1c5c1d2760640faf
[bbtk.git] / kernel / src / bbtkComplexBlackBoxDescriptor.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkComplexBlackBoxDescriptor.cxx,v $
4   Language:  C++
5   Date:      $Date: 2012/11/14 07:12:00 $
6   Version:   $Revision: 1.22 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30   
31
32 /**
33  *  \file 
34  *  \brief Class bbtk::ComplexBlackBoxDescriptor : describes a ComplexBlackBox (constituents, connections) and is able to create an instance of it.
35  */
36 #include "bbtkComplexBlackBoxDescriptor.h"
37 #include "bbtkComplexBlackBox.h"
38 //#include "bbtkFactory.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkUtilities.h"
41
42 #define bbtkDMessage(key,level,mess) \
43   bbtkMessage(key,level,"["<<GetFullTypeName()<<"] "<<mess)
44 #define bbtkDDebugMessage(key,level,mess)       \
45   bbtkDebugMessage(key,level,"["<<GetFullTypeName()<<"] "<<mess)
46
47 namespace bbtk
48 {
49    //=======================================================================
50   /// 
51   ComplexBlackBoxDescriptor::Pointer 
52   ComplexBlackBoxDescriptor::New(const std::string& name)
53   {
54     bbtkDebugMessage("object",1,"##> ComplexBlackBoxDescriptor::New(\""<<name<<"\")"<<std::endl);
55     ComplexBlackBoxDescriptor::Pointer p = 
56       MakePointer(new ComplexBlackBoxDescriptor(name));
57     bbtkDebugMessage("object",1,"<## ComplexBlackBoxDescriptor::New(\""<<name<<"\")"<<std::endl);
58     return p;
59   }
60   //=======================================================================
61
62   //=======================================================================
63   /// Default ctor
64   ComplexBlackBoxDescriptor::ComplexBlackBoxDescriptor(const std::string& name)
65   {
66     bbtkDDebugMessage("object",2,"==> ComplexBlackBoxDescriptor(\""<<name<<"\")"<<std::endl);
67         SetTypeOfScript(TS_SCRIPT_COMPLEXBOX);
68     SetTypeName(name);
69     AddToCategory("complex box");
70     mPrototype = ComplexBlackBox::New(name+std::string("Prototype"),
71                                       MakePointer(this,true));
72     mPrototype->SetAsPrototype();
73     bbtkDDebugMessage("object",2,"<== ComplexBlackBoxDescriptor(\""<<name<<"\")"<<std::endl);
74   }
75   //=======================================================================
76
77
78
79   //=======================================================================
80   /// Default dtor
81   ComplexBlackBoxDescriptor::~ComplexBlackBoxDescriptor()
82   {
83     bbtkDDebugMessage("object",2,"==> ~ComplexBlackBoxDescriptor()"<<std::endl);
84     mPrototype.reset();
85     bbtkDDebugMessage("object",2,"<== ~ComplexBlackBoxDescriptor()"<<std::endl);
86   }
87   //=======================================================================
88
89   //=========================================================================
90   /// Check
91   void ComplexBlackBoxDescriptor::Check(bool recursive) const
92   {
93     mPrototype->Check(recursive);
94   }
95   //=========================================================================
96
97   //=======================================================================
98   /// Creates an instance of name <name> of the ComplexBlackBox of which this is the descriptor 
99   BlackBox::Pointer 
100   ComplexBlackBoxDescriptor::NewBlackBox(const std::string& name)
101   {
102     bbtkDDebugMessage("kernel",5,
103                       "ComplexBlackBoxDescriptor::NewBlackBox(\""
104                       <<name<<"\")"
105                       <<std::endl);
106     
107     return mPrototype->bbClone(name);
108
109
110   }
111   //=======================================================================
112
113   /*
114   //=======================================================================
115   /// Release
116   void ComplexBlackBoxDescriptor::Release(bool release_package)
117   {
118   }
119   //=======================================================================
120   */
121
122   //=======================================================================
123   /// Adds a black box to the complex box
124   void ComplexBlackBoxDescriptor::Add ( const std::string& type,
125                                         const std::string& name
126                                         )
127   {
128     bbtkDDebugMessage("kernel",5,
129                         "ComplexBlackBoxDescriptor::Add(\""
130                         <<type<<"\",\""<<name<<"\")"
131                         <<std::endl);
132     
133     // 
134     if (!GetFactory()) 
135       { 
136         bbtkError("ComplexBlackBoxDescriptor::Add : no factory set");
137       }
138     
139     // Verify that a box with the same name does not exist already
140     if ( mPrototype->bbUnsafeGetBlackBox( name ) ) 
141       {
142         bbtkError("a black box \""<<name<<"\" already exists");
143       }
144     // ok : create new one
145     mPrototype->bbAddBlackBox ( GetFactory()->NewBlackBox(type,name) );
146
147
148   }
149   //=======================================================================
150   
151   //=======================================================================
152   /// Removes a black box from the complex box
153   void ComplexBlackBoxDescriptor::Remove( const std::string& name, 
154                                           bool remove_connections)
155   {    
156     mPrototype->bbRemoveBlackBox(name,remove_connections);
157   }
158   //=======================================================================
159
160
161   //=======================================================================
162   /// Adds a black box to the execution list 
163   void ComplexBlackBoxDescriptor::AddToExecutionList ( const std::string& box)
164   {
165     bbtkDDebugMessage("kernel",5,
166                       "ComplexBlackBoxDescriptor::AddToExecutionList(\""
167                       <<box<<"\""
168                       <<std::endl);
169     // Verify that the box exists
170     BlackBox::Pointer b = mPrototype->bbUnsafeGetBlackBox( box ); 
171     if ( !b ) 
172       {
173         bbtkError("the black box \""<<box<<"\" does not exist");
174       }
175     // ok 
176     mPrototype->bbAddToExecutionList ( box  );
177
178
179     }
180
181
182   //=======================================================================
183   /// Connects two black boxes of the complex box
184   void ComplexBlackBoxDescriptor::Connect ( const std::string& from,
185                                             const std::string& output,
186                                             const std::string& to,
187                                             const std::string& input
188                                             )
189   {
190     bbtkDDebugMessage("kernel",5,
191                         "ComplexBlackBoxDescriptor::Connect(\""
192                         <<from<<"\",\""<<output<<"\",\""
193                         <<to<<"\",\""<<input
194                         <<"\")"
195                         <<std::endl);
196   // 
197     if (!GetFactory()) 
198       { 
199         bbtkError("ComplexBlackBoxDescriptor::Connect : no factory set");
200       }
201     
202
203   // Verify that a box with the same name does not exist already
204     BlackBox::Pointer bbfrom = mPrototype->bbGetBlackBox( from );
205     if ( !bbfrom ) 
206       {
207         bbtkError("the black box \""<<from<<"\" does not exist");
208       }
209     BlackBox::Pointer bbto = mPrototype->bbGetBlackBox( to );
210     if ( !bbto ) 
211       {
212         bbtkError("the black box \""<<to<<"\" does not exist");
213       }
214     
215     Connection::Pointer c 
216       = GetFactory()->NewConnection( bbfrom, output, bbto, input );
217
218     mPrototype->bbAddConnection(c);
219
220
221   }
222   //=======================================================================
223
224
225   //=======================================================================
226   /// Defines an input of the complex box
227   void ComplexBlackBoxDescriptor::DefineInput ( const std::string& name,
228                                                 const std::string& box,
229                                                 const std::string& input,
230                                                 const std::string& help)
231   {
232     bbtkDDebugMessage("kernel",5,
233                         "ComplexBlackBoxDescriptor::DefineInput(\""
234                         <<name<<"\",\""<<box<<"\",\""
235                         <<input<<"\",\""<<help
236                         <<"\")"
237                         <<std::endl);
238
239     BlackBox::Pointer bb = mPrototype->bbGetBlackBox( box );
240     if ( !bb ) 
241       {
242         bbtkError("the black box \""<<box<<"\" does not exist");
243       }
244
245     if (!bb->bbHasInput(input) )
246       {
247         bbtkError("the black box \""<<box<<"\" does not have input \""
248                   <<input<<"\"");
249       }
250     
251     const BlackBoxInputDescriptor* d = 
252       bb->bbGetDescriptor()->GetInputDescriptor(input);
253     AddInputDescriptor ( new ComplexBlackBoxInputDescriptor 
254                          ( typeid(ComplexBlackBoxDescriptor),
255                            name,
256                            help,
257                            d->GetNature(),
258                            box,
259                            input,
260                            d->GetTypeInfo()));
261     
262     
263
264   }
265   //=======================================================================
266
267   //=======================================================================
268   /// Defines an output of the complex box
269   void ComplexBlackBoxDescriptor::DefineOutput ( const std::string& name,
270                                                  const std::string& box,
271                                                  const std::string& output,
272                                                  const std::string& help)
273   {
274     bbtkDDebugMessage("kernel",5,
275                         "ComplexBlackBoxDescriptor::DefineOutput(\""
276                         <<name<<"\",\""<<box<<"\",\""
277                         <<output<<"\",\""<<help
278                         <<"\")"
279                         <<std::endl);
280
281     BlackBox::Pointer bb = mPrototype->bbGetBlackBox( box );
282     if ( !bb ) 
283       {
284         bbtkError("the black box \""<<box<<"\" does not exist");
285       }
286
287     if (!bb->bbHasOutput(output) )
288       {
289         bbtkError("the black box \""<<box<<"\" does not have output \""
290                   <<output<<"\"");
291       }
292     
293     const BlackBoxOutputDescriptor* d = 
294       bb->bbGetDescriptor()->GetOutputDescriptor(output);
295     AddOutputDescriptor ( new ComplexBlackBoxOutputDescriptor 
296                           ( typeid(ComplexBlackBoxDescriptor),
297                             name,
298                             help,
299                             d->GetNature(),
300                             box,
301                             output,
302                             d->GetTypeInfo()));
303     
304     
305
306   }
307   //=======================================================================
308
309   //=======================================================================
310   void ComplexBlackBoxDescriptor::PrintBlackBoxes()
311   {
312     mPrototype->bbPrintBlackBoxes(); 
313   }
314   //=======================================================================
315
316
317   //=======================================================================
318   void ComplexBlackBoxDescriptor::InsertHTMLGraph( std::ofstream& s , 
319                                                    int detail, int level, 
320                                                    const std::string& output_dir, bool relative_link )   
321   {
322     this->mPrototype->bbInsertHTMLGraph( s, 
323                                          detail, level, 
324                                          false, 
325                                          output_dir,
326                                          relative_link );
327   }
328   //=======================================================================
329
330   //=========================================================================
331   void ComplexBlackBoxDescriptor::InsertHtmlHelp ( std::ofstream& s, 
332                                                    int detail, int level,
333                                                    const std::string& output_dir, bool relative_link)
334   {
335     bbtkDDebugMessage("kernel",9,
336                       "ComplexBlackBoxDescriptor::InsertHtmlHelp()"
337                        <<std::endl);
338     
339     //-------------
340     // General info 
341     std::string name = GetTypeName();
342     Utilities::html_format(name);
343
344     //   std::ofstream* s = &s1;
345
346     (s) << "<p><hr>\n";
347     (s) << "<a name=\""<<name<<"\"></a>\n";
348     (s) << //"Top:&nbsp;
349       "<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
350     // (s) << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
351     // (s) << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
352     (s) << "<h2 class=\"section\">"<<name<<"</h2>\n";
353
354
355     std::string descr = GetDescription();
356     //Utilities::html_format(descr);
357     
358     std::string author = GetAuthor();
359     Utilities::html_format(author);
360     
361     std::vector<std::string> categories;
362     // Split the category string 
363     std::string delimiters = ";,";
364     Utilities::SplitString(GetCategory(),
365                            delimiters,categories);
366
367         
368     (s) << "<p><TABLE cellspacing=0  cellpadding=3>\n";
369     (s) << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
370         << descr << "</TD></TR>\n";
371
372     (s) << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
373         << author << "</TD></TR>\n";
374
375     (s) << "<TR><TD style='vertical-align: top;'><b> Category(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  ";
376     std::vector<std::string>::iterator ci;
377     for (ci=categories.begin(); ci!=categories.end(); ++ci)
378       {
379         s << "<a href=\"../index-category.html#"<< *ci <<"\">" << *ci 
380           << "</a>&nbsp;\n";
381       }
382     s << "</TD></TR>\n";      
383     std::string inc = GetScriptFileName();
384     if (inc.size()>0) 
385       {
386         s << "<TR><TD style='vertical-align: top;'><b> To use it </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> include ";
387         // s << inc << "&nbsp;&nbsp;<a href=\"../../../bbs/"<<inc<<"\">[source]</a>";
388         // LG TODO : USE PACKAGE BBS PATH
389         s << inc << "&nbsp;&nbsp;<a href=\""<<inc<<"\">[source]</a>";
390         s << "</TD></TR>\n";
391         
392       }
393     
394     const ComplexBlackBox::BlackBoxMapType& B = mPrototype->bbGetBlackBoxMap();
395         
396     if (B.size()) 
397     {
398            (s) << "<TR><TD style='vertical-align: top;'><b> Uses </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  ";
399
400            std::set<BlackBoxDescriptor::Pointer> pdeps;
401            ComplexBlackBox::BlackBoxMapType::const_iterator b;
402            for ( b = B.begin(); b != B.end(); ++b ) 
403            {
404              BlackBoxDescriptor::Pointer d = b->second->bbGetDescriptor();
405               if (pdeps.find(d) != pdeps.end()) 
406             continue;
407               pdeps.insert(d);
408
409               Package::Pointer p = d->GetPackage();
410             
411               std::string name = b->second->bbGetTypeName();
412
413               std::string url;
414               if (relative_link) 
415                  url = p->GetDocRelativeURL();
416               else 
417                  url = p->GetDocURL();
418                    
419               s << "<a href=\"" <<url<<"#"<<name<<"\">" 
420                 << p->GetName()<<"::"<<name<<"</a>\n";
421             }   // for
422         
423             (s) << "</TD></TR>\n";
424
425      } // If B.size
426
427      (s) << "</TABLE>\n";
428
429  
430    //-------------
431     // Graph
432     InsertHTMLGraph( s , detail,level, output_dir, relative_link);
433     
434     //-------------
435     // Inputs
436     std::string col("#CCCCFF");
437     
438     //  (s) << "<h3 class=\"subsection\">Inputs</h3>\n";
439     (s) << "<p><TABLE border=1 cellspacing=0 cellpadding=3>\n";
440     (s) << "<TR><TD colspan=3 align=center bgcolor=\""<<col
441       <<"\">Inputs</TD></TR>\n";
442     const BlackBoxDescriptor::InputDescriptorMapType& imap = 
443       GetInputDescriptorMap();
444     
445     InputDescriptorMapType::const_iterator in;
446     
447     for ( in = imap.begin();  in != imap.end(); ++in ) 
448       {
449         std::string name(in->second->GetName());
450         Utilities::html_format(name);
451         
452         std::string type("<");
453         type += in->second->GetTypeName();    
454         type += ">";
455         Utilities::html_format(type);
456         
457         std::string descr(in->second->GetDescription());
458         //Utilities::html_format(descr);
459
460 /*EED 10/11/2009
461         (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
462           << "<TD style='vertical-align: top;'><I><PRE> "<<type<<" </PRE></I></TD>"
463           << "<TD style='vertical-align: top;'>"<<descr<<"</TD></TR>\n";
464 */
465
466         (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
467           << "<TD style='vertical-align: top;'><I><PRE> "<<descr<<" </PRE></I></TD>"
468           << "<TD style='vertical-align: top;'>"<<type<<"</TD></TR>\n";
469         
470       }
471     //  (s) << "</TABLE>\n";
472     
473     
474     //-------------
475     // Outputs
476     //  (s) << "<h3 class=\"subsection\">Outputs</h3>\n";
477     //  (s) << "<TABLE border=1 cellspacing=0>\n";
478     (s) << "<TR><TD colspan=3 align=center bgcolor=\""<<col
479       <<"\">Outputs</TD></TR>\n";
480     
481     const BlackBoxDescriptor::OutputDescriptorMapType& omap = 
482       GetOutputDescriptorMap();
483     
484     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
485     
486     for ( o = omap.begin();  o != omap.end(); ++o ) 
487       {
488         std::string name(o->second->GetName());
489         Utilities::html_format(name);
490         
491         std::string type("<");
492         type += o->second->GetTypeName();    
493         type += ">";
494         Utilities::html_format(type);
495         
496         std::string descr(o->second->GetDescription());
497         //Utilities::html_format(descr);
498         
499 /*EED 10/11/2009
500         (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
501           << "<TD style='vertical-align: top;'><I><PRE> "<<type<<" </PRE></I></TD>"
502           << "<TD style='vertical-align: top;'>"<<descr<<"</TD></TR>\n";
503 */      
504         (s) << "<TR><TD style='vertical-align: top;'><B><PRE> "<<name<<" </PRE></B></TD>"
505           << "<TD style='vertical-align: top;'><I><PRE> "<<descr<<" </PRE></I></TD>"
506           << "<TD style='vertical-align: top;'>"<<type<<"</TD></TR>\n";
507
508       }
509     (s) << "</TABLE>\n";
510
511     //------------
512     // End
513
514
515    }
516   //=========================================================================
517  
518
519   //=======================================================================
520   void ComplexBlackBoxDescriptor::GetHelp(bool full) const
521   {
522     if (full) bbtkMessage("help",1,"Complex Black Box <"<<
523                           GetPackage()->GetName()<<"::"
524                           <<GetTypeName()<<">"<<std::endl);
525     bbtkMessage("help",1," "                << GetDescription() <<std::endl);
526     bbtkMessage("help",1," By : "           << GetAuthor()      <<std::endl);
527     bbtkMessage("help",1," Category(s) : "  << GetCategory()     <<std::endl);    
528     if (mInput.size()) 
529       bbtkMessage("help",1," * Inputs : "<<std::endl);
530     else 
531       bbtkMessage("help",1," * No inputs"<<std::endl);
532     InputDescriptorMapType::const_iterator i;
533     unsigned int namelmax = 0;
534     unsigned int typelmax = 0;
535     unsigned int natlmax = 0;
536     for ( i = mInput.begin();  i != mInput.end(); ++i ) 
537     {
538            if (i->second->GetName().size()>namelmax) 
539              namelmax = i->second->GetName().size();
540            if (i->second->GetTypeName().size()>typelmax) 
541              typelmax = i->second->GetTypeName().size();
542            if (i->second->GetNature().size()>natlmax) 
543              natlmax = i->second->GetNature().size();
544     }
545     OutputDescriptorMapType::const_iterator o;
546     if (full) 
547     {
548            for ( o = mOutput.begin();  o != mOutput.end(); ++o ) 
549            {
550              if (o->second->GetName().size()>namelmax) 
551                namelmax = o->second->GetName().size();
552             if (o->second->GetTypeName().size()>typelmax) 
553                typelmax = o->second->GetTypeName().size();
554            if (o->second->GetNature().size()>natlmax) 
555              natlmax = o->second->GetNature().size();
556            }
557     }
558     //
559
560     for ( i = mInput.begin();  i != mInput.end(); ++i ) 
561     {
562            std::string name(i->second->GetName());
563            name += "'";
564            name.append(1+namelmax-name.size(),' ');
565            std::string type(i->second->GetTypeName());
566            type += ">";
567            type.append(1+typelmax-type.size(),' ');
568            std::string nature(i->second->GetNature());
569            nature += "]";
570            nature.append(1+natlmax-nature.size(),' ');
571            bbtkMessage("help",1,
572                        "    '"<<name
573                        <<" <"<<type
574                        <<" ["<<nature
575                        <<" : "<<i->second->GetDescription()<<std::endl);
576     }
577     if (full) 
578     {
579            if (mOutput.size()) 
580              bbtkMessage("help",1," * Outputs : "<<std::endl);
581            else 
582              bbtkMessage("help",1," * No outputs"<<std::endl);
583            for ( o = mOutput.begin();  o != mOutput.end(); ++o ) 
584            {
585              std::string name(o->second->GetName());
586              name += "'";
587              name.append(1+namelmax-name.size(),' ');
588              std::string type(o->second->GetTypeName());
589              type += ">";
590              type.append(1+typelmax-type.size(),' ');
591              std::string nature(o->second->GetNature());
592              nature += "]";
593              nature.append(1+natlmax-nature.size(),' ');
594              bbtkMessage("help",1,
595                        "    '"<<name
596                          <<" <"<<type
597                          <<" ["<<nature
598                          <<" : "<<o->second->GetDescription()<<std::endl);
599            }
600     }
601     if (full) 
602     {
603            const ComplexBlackBox::BlackBoxMapType& B = mPrototype->bbGetBlackBoxMap();
604         
605            if (B.size()) 
606              bbtkMessage("help",1," * Boxes : "<<std::endl);
607            else 
608              bbtkMessage("help",1," * No boxes"<<std::endl);
609         
610            ComplexBlackBox::BlackBoxMapType::const_iterator b;
611            for ( b = B.begin(); b != B.end(); ++b ) 
612            {
613              bbtkMessage("help",1,"    '"<<b->second->bbGetName()<<
614                          "' <"
615                          << b->second->bbGetDescriptor()->GetPackage()->GetName() 
616                          <<"::"
617                          <<b->second->bbGetTypeName()<<">"<<std::endl);
618            }
619     }
620
621   }   
622   //=======================================================================
623
624   //==========================================================================
625   std::string ComplexBlackBoxDescriptor::GetObjectName() const
626   {
627     return std::string("ComplexBlackBoxDescriptor '")+GetFullTypeName()
628       +std::string("'");
629   }
630   //==========================================================================
631   //=======================================================================
632   std::string ComplexBlackBoxDescriptor::GetObjectInfo() const
633   {
634     std::string i;
635     return i;     
636   }
637   //=======================================================================
638  //==========================================================================
639 size_t  ComplexBlackBoxDescriptor::GetObjectSize() const 
640 {
641   size_t s = Superclass::GetObjectSize();
642   s += ComplexBlackBoxDescriptor::GetObjectInternalSize();
643   return s;
644   }
645   //==========================================================================
646   //==========================================================================
647 size_t  ComplexBlackBoxDescriptor::GetObjectInternalSize() const 
648 {
649   size_t s = sizeof(ComplexBlackBoxDescriptor);
650   return s;
651   }
652   //==========================================================================
653   //==========================================================================
654   size_t  ComplexBlackBoxDescriptor::GetObjectRecursiveSize() const 
655   {
656     size_t s = Superclass::GetObjectRecursiveSize();
657     s += ComplexBlackBoxDescriptor::GetObjectInternalSize();
658     s += mPrototype->GetObjectRecursiveSize();
659     return s;
660   }
661   //==========================================================================
662
663         
664 }