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