]> Creatis software - bbtk.git/blob - kernel/src/bbtkExecuter.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkExecuter.cxx
1 /*=========================================================================
2          
3   Program:   bbtk
4   Module:    $RCSfile: bbtkExecuter.cxx,v $ $
5   Language:  C++
6   Date:      $Date: 2008/04/22 06:59:31 $
7   Version:   $Revision: 1.19 $
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  *  \file 
20  *  \brief class Executer: level 0 of script execution (code)
21  */
22
23 #include "bbtkExecuter.h"
24 #include "bbtkMessageManager.h"
25 #include "bbtkFactory.h"
26 #include "bbtkUtilities.h"
27 #include <fstream>
28
29 #ifdef _USE_WXWIDGETS_
30 #include <wx/textdlg.h>
31 #endif
32
33 #include "bbtkWxBlackBox.h"
34
35 #include "bbtkConfigurationFile.h"
36
37 namespace bbtk
38 {
39   //=======================================================================
40   Executer::Pointer Executer::New()
41   {
42     bbtkDebugMessage("Kernel",9,"Executer::New()"<<std::endl);
43     return MakePointer(new Executer());
44   }
45   //=======================================================================
46
47   //=======================================================================
48   Executer::Executer()
49     : 
50     mFactory(),
51     mRootPackage(),
52     mRootCBB(),
53     mNoExecMode(false),
54     mDialogMode(NoDialog)
55   {
56     bbtkDebugMessageInc("Kernel",9,"Executer::Executer()" <<std::endl);
57     mFactory = Factory::New();
58     // The smart pointer on this is not made yet (is made by New) 
59     // -> create it to pass it to the factory
60     // We have to "lock" the smart pointer because the factory
61     // only keeps a weak pointer on the executer
62     // -> this would auto-destroy !!
63     mFactory->SetExecuter(MakePointer(this,true));
64     Reset();
65     bbtkDebugDecTab("Kernel",9);
66   }
67   //=======================================================================
68
69   //=======================================================================
70   Executer::~Executer()
71   {
72      bbtkDebugMessageInc("Kernel",9,"==> Executer::~Executer()" <<std::endl);
73      mOpenDefinition.clear();
74      mOpenPackage.clear();
75      mFactory->Reset();
76      mFactory.reset();
77      bbtkDebugDecTab("Kernel",9);
78   }
79   //=======================================================================
80
81   //=======================================================================
82    /// Loads a package
83     void Executer::LoadPackage(const std::string &name )
84    {
85      GetFactory()->LoadPackage(name);
86    }
87   //=======================================================================
88
89   //=======================================================================
90     /// Unloads a package
91     void Executer::UnLoadPackage(const std::string &name )
92     {
93       GetFactory()->UnLoadPackage(name);
94     }
95   //=======================================================================
96
97   //=======================================================================
98   void Executer::Reset()
99   {
100     bbtkDebugMessageInc("Kernel",9,"Executer::Reset()" <<std::endl);
101
102     GetFactory()->CheckPackages();
103  
104     mOpenDefinition.clear();
105     mOpenPackage.clear();
106     GetFactory()->Reset();
107
108     // Create user package
109     Package::Pointer p =
110       Package::New("user","internal to bbi",
111                    "User defined black boxes",
112                    "",
113                    BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));
114     // Insert the user package in the factory
115     GetFactory()->InsertPackage(p);
116     // And in the list of open packages
117     mOpenPackage.push_back(p);
118     mRootPackage = p;
119
120     // Create user workspace
121     ComplexBlackBoxDescriptor::Pointer r = 
122       ComplexBlackBoxDescriptor::New("workspace"); 
123     //    mRootCBB->Reference();
124     r->SetFactory(GetFactory());
125     r->AddToAuthor("bbi (internal)");
126     r->AddToDescription("User's workspace");
127     mOpenDefinition.push_back(CBBDefinition(r,"user"));
128     // Register it into the user package
129     p->RegisterBlackBox(r);
130     mRootCBB = r;
131
132     //    Object::PrintObjectListInfo();
133     //  GetFactory()->CheckPackages();
134
135     bbtkDebugDecTab("Kernel",9);
136   }
137   //=======================================================================
138
139   //=======================================================================
140   /// changes the workspace name
141   void Executer::SetWorkspaceName( const std::string& n )
142   {
143     GetUserPackage()->ChangeBlackBoxName( GetWorkspace()->GetTypeName(), n );
144   }
145   //=======================================================================
146
147   //=======================================================================
148   void Executer::BeginPackage (const std::string &name)
149   {
150      bbtkDebugMessageInc("Kernel",9,"Executer::BeginPackage(\""<<name<<"\")"
151                         <<std::endl);
152      Package::Pointer p;
153      try 
154       {
155          p = GetFactory()->GetPackage(name);
156       }
157     catch (Exception e)
158       {
159         p = Package::New(name,
160                          "",
161                          "",
162                          "",
163                          BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));
164         GetFactory()->InsertPackage(p);
165       }
166      mOpenPackage.push_back(p);
167   }
168   //=======================================================================
169
170   //=======================================================================
171   void Executer::EndPackage()
172   {
173     if (mOpenPackage.size()>1) mOpenPackage.pop_back();
174   }
175   //=======================================================================
176
177   //=======================================================================
178   void Executer::Define (const std::string &name,
179                          const std::string &pack,
180                          const std::string &scriptfilename)
181   {
182     bbtkDebugMessageInc("Kernel",9,"Executer::Define(\""<<name<<
183                         ","<<pack<<"\")"
184                         <<std::endl);
185
186     ComplexBlackBoxDescriptor::Pointer b 
187       = ComplexBlackBoxDescriptor::New(name);
188     b->SetFactory(GetFactory());
189     b->SetScriptFileName(scriptfilename);
190     mOpenDefinition.push_back( CBBDefinition( b, pack ) );
191     
192     bbtkDebugDecTab("Kernel",9);
193   }
194   //=======================================================================
195
196   //=======================================================================
197   /// Sets the file name to use for the current definition
198   /// (Used to set it after the Define command)
199   void Executer::SetCurrentFileName (const std::string &name )
200   {
201     mOpenDefinition.back().box->SetScriptFileName(name);
202   }
203   //=======================================================================
204
205   //=======================================================================
206   void Executer::EndDefine ()
207   {
208     bbtkDebugMessageInc("Kernel",9,"Executer::EndDefine(\""
209                         <<Current()->GetTypeName()<<"\")" 
210                         <<std::endl);
211     // Does current package exist ?
212     Package::Pointer p;
213     std::string pname(mOpenDefinition.back().package);
214     if (pname.size()>0)
215       {
216         try
217           {
218             p = GetFactory()->GetPackage(pname);
219           }
220         catch (Exception e)
221           {
222             p = Package::New(pname,
223                              "",
224                              "",
225                              "",
226                              BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));
227             GetFactory()->InsertPackage(p);
228           }
229       }
230     else
231       {
232         p = mOpenPackage.back().lock();
233       }
234     p->RegisterBlackBox(Current());
235     
236     mOpenDefinition.pop_back();
237   }
238   //======================================================================= 
239
240   //=======================================================================  
241   void Executer::Kind(const std::string& kind)
242   {
243     if (kind=="ADAPTOR")
244       {
245         Current()->AddToCategory("adaptor");
246         Current()->SetKind(bbtk::BlackBoxDescriptor::ADAPTOR);
247       }
248     else if (kind=="DEFAULT_ADAPTOR")
249       {
250         Current()->AddToCategory("adaptor");
251         Current()->SetKind(bbtk::BlackBoxDescriptor::DEFAULT_ADAPTOR);
252       }
253     if (kind=="GUI")
254       {
255         Current()->AddToCategory("gui");
256         Current()->SetKind(bbtk::BlackBoxDescriptor::GUI);
257       }
258     else if (kind=="DEFAULT_GUI")
259       {
260         Current()->AddToCategory("gui");
261         Current()->SetKind(bbtk::BlackBoxDescriptor::DEFAULT_GUI);
262       }
263     else
264       {
265         bbtkError("Unknown box kind : '"<<kind<<"'. "
266                   <<"Valid kinds are 'ADAPTOR','DEFAULT_ADAPTOR',"
267                   <<"'GUI','DEFAULT_GUI'");
268       }
269   }
270   //=======================================================================
271
272   //=======================================================================
273   void Executer::Create ( const std::string& nodeType, 
274                           const std::string& nodeName)
275   {
276      Current()->Add(nodeType,nodeName);
277   }
278   //=======================================================================
279
280   //=======================================================================
281   void Executer::Destroy(const std::string &boxName)
282   {
283     Current()->Remove(boxName,true);
284   }
285   //=======================================================================
286
287   //=======================================================================
288   void Executer::Connect (const std::string &nodeFrom,
289                           const std::string &outputLabel,
290                           const std::string &nodeTo, 
291                           const std::string &inputLabel)
292   {
293     Current()->Connect(nodeFrom, outputLabel, nodeTo, inputLabel);
294   }
295   //=======================================================================
296
297   //=======================================================================
298   void Executer::Execute (const std::string &nodeName) 
299   {
300     // if in root
301     if (Current()==GetWorkspace()) 
302      {
303         if (!mNoExecMode) 
304         {
305            Current()->GetPrototype()->bbGetBlackBox(nodeName)->bbExecute(true);
306         }
307      }
308      else 
309      {
310         Current()->AddToExecutionList(nodeName) ;
311      }
312   }
313   //=======================================================================
314
315   //=======================================================================
316   void Executer::DefineInput ( const std::string &name,
317                                const std::string &box,
318                                const std::string &input,
319                                const std::string& help)
320   {
321     // If the input is defined in the Root box
322     if (Current()==GetWorkspace()) 
323       {
324       // If the dialog mode is set to NoDialog
325       // and the user passed the name in the Inputs map 
326       // then the associated value is set to the box.input
327       // This is the way command line parameters are passed to the Root box
328          if (mDialogMode == NoDialog) 
329          {
330          // find if name is in mInputs
331             std::map<std::string,std::string>::iterator i;
332             i = mInputs.find(name);
333             if (i!=mInputs.end()) {
334                Set(box,input,(*i).second);
335             }
336          }
337         // If the dialog mode is set to TextDialog
338         // The user is prompted for the value
339         else if (mDialogMode == TextDialog) 
340         {
341            std::cout << name << "=";
342            std::string ans;
343            std::cin >> ans;
344            Set(box,input,ans);
345         }
346 #ifdef _USE_WXWIDGETS_
347        // If the dialog mode is set to GraphicalDialog
348        // A dialog box is pop up
349        else if (mDialogMode == GraphicalDialog) 
350        {
351           std::string mess("Enter the value of '");
352           mess += name;
353           mess += "' (";
354           mess += help;
355           mess += ")";
356           std::string title(name);
357           title += " ?";
358           std::string ans = wx2std ( wxGetTextFromUser( std2wx (mess), std2wx(title)));
359           Set(box,input,ans); 
360        }
361 #endif
362     }
363
364     Current()->DefineInput(name,box,input,help);
365
366   }
367   //=======================================================================
368
369   //=======================================================================
370    void Executer::DefineOutput ( const std::string &name,
371                                  const std::string &box,
372                                  const std::string &output,
373                                  const std::string& help)
374   {
375     Current()->DefineOutput(name,box,output,help);
376   }
377   //=======================================================================
378
379   //=======================================================================
380   void Executer::Set (const std::string &box,
381                       const std::string &input,
382                       const std::string &value)
383   {
384     BlackBox::Pointer b = Current()->GetPrototype()->bbGetBlackBox(box);
385     // Looks for the adaptor
386
387     if ( b->bbGetInputType(input) !=  typeid(std::string) ) 
388       {
389         BlackBox::Pointer a =
390            GetFactory()->NewAdaptor(typeid(std::string),
391                                     b->bbGetInputType(input),
392                                     "tmp");
393          if (!a) 
394            {
395              bbtkError("No <"<<
396                        TypeName(b->bbGetInputType(input))
397                        <<"> to <std::string> found");
398            }
399          std::string v(value);
400          a->bbSetInput("In",v);
401          a->bbExecute();
402          b->bbSetInput(input,a->bbGetOutput("Out"));
403          //         a->Delete();
404       }
405     else 
406       {
407       std::string v(value);
408       b->bbSetInput(input,v);
409       }
410   }
411   //=======================================================================
412
413   //=======================================================================
414   std::string Executer::Get(const std::string &box,
415                             const std::string &output)
416   {
417     BlackBox::Pointer b = Current()->GetPrototype()->bbGetBlackBox(box);
418     // Looks for the adaptor
419     if (b->bbGetOutputType(output) != typeid(std::string)) 
420       {
421         BlackBox::Pointer a =
422           GetFactory()->NewAdaptor(
423                                    b->bbGetOutputType(output),
424                                    typeid(std::string),
425                                    "tmp");
426         if (!a) 
427           {
428             bbtkError("No <"<<
429                       TypeName(b->bbGetOutputType(output))
430                       <<"> to <std::string> found");
431           }
432         b->bbExecute();
433         
434         a->bbSetInput("In",b->bbGetOutput(output));
435         a->bbExecute();
436         std::string r = a->bbGetOutput("Out").unsafe_get<std::string>();
437         //std::string v = *((std::string*)a->bbGetOutput("Out")) ;
438         //   std::cout << a->bbGetOutput("Out").unsafe_get<std::string>() 
439         //             << std::endl;
440         //std::string v(value);
441         //b->bbSetInput(input,a->bbGetOutput("Out"));
442         //        a->bbDelete();
443         return r;
444       }
445     else
446       {
447         b->bbExecute();
448         return b->bbGetOutput(output).unsafe_get<std::string>();
449         // std::string v = *((std::string*)b->bbGetOutput(output)) ;
450         // std::cout << b->bbGetOutput("Out").unsafe_get<std::string>() 
451         //   << std::endl;
452         // b->bbSetInput(input,&v);
453       }
454   }
455   //=======================================================================
456
457   //=======================================================================
458   void Executer::Author(const std::string &authorName)
459   {
460     Current()->AddToAuthor(authorName,Current()==GetWorkspace());
461   }
462   //=======================================================================
463
464   //=======================================================================
465   void Executer::Category(const std::string &category)
466   {
467     Current()->AddToCategory(category,Current()==GetWorkspace());
468   }
469   //=======================================================================
470
471   //=======================================================================
472   void Executer::Description(const std::string &d)
473   {
474     Current()->AddToDescription(d,Current()==GetWorkspace());
475   }
476   //=======================================================================
477
478   //=======================================================================
479   /// prints the list of the boxes of the current descriptor
480   void Executer::PrintBoxes()
481   {
482     bbtkMessageInc("Help",1,"The black box descriptor \""
483                    <<Current()->GetTypeName()<<"\" contains : "<<std::endl);
484     Current()->PrintBlackBoxes();
485     bbtkDecTab("Help",1);
486  }
487   //=======================================================================
488
489   //=======================================================================
490   std::string Executer::ShowGraph(const std::string &nameblackbox, 
491                                   const std::string &detailStr, 
492                                   const std::string &levelStr,
493                                   const std::string &output_html,
494                                   const std::string &custom_header,
495                                   const std::string &custom_title,
496                                   bool system_display )
497   {
498     int detail  =       atoi(detailStr.c_str());
499     int level   =       atoi(levelStr.c_str());
500
501     std::string filename_rootHtml (output_html) ;
502     std::string simplefilename_rootHtml ( Utilities::get_file_name(output_html));
503
504     bool relative_link = true;
505
506     // No output provided : automatic generation
507     if (output_html.length() == 0)
508       {
509         // Don't pollute the file store with  "temp_dir" directories ...    
510         std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
511         
512         char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
513         
514         std::string directory = default_doc_dir; 
515         if (c != '/' && c !='\\') directory = directory + "/";
516         directory = directory +  "temp_dir";    
517         
518         filename_rootHtml = directory + "/" + "User.html";
519         simplefilename_rootHtml = "User.html" ;
520
521         // Creating directory
522         std::string command0("mkdir \"" +directory + "\"");
523         system( command0.c_str() );
524
525         relative_link = false;
526       }
527
528     Package::Pointer p;
529     try
530     {
531        p = GetFactory()->GetPackage(nameblackbox);
532     }
533     catch (Exception e)
534     {
535       p = GetUserPackage();
536     }
537     // Generating documentation-help of workspace
538     p->SetDocURL(filename_rootHtml);
539     p->SetDocRelativeURL(simplefilename_rootHtml);
540
541     p->CreateHtmlPage(filename_rootHtml,"bbi","user package",custom_header,custom_title,detail,level,relative_link);
542
543     std::string page = filename_rootHtml;
544     /*
545     try 
546     {
547        ShowGraphTypes(nameblackbox);
548     }
549     catch (bbtk::Exception a)
550     {
551        std::cout <<"EXC"<<std::endl;
552        page = ShowGraphInstances(nameblackbox,detail,level,system_display);
553     }
554     */
555     return page;
556   }
557   //=======================================================================
558
559   //=======================================================================
560   /// Generate a png file with the actual pipeline (Graphviz-dot needed)
561   std::string Executer::ShowGraphInstances(const std::string &nameblackbox, int detail, int level,
562                                            bool system_display)
563   {
564
565     BlackBox::Pointer blackbox;
566     if (nameblackbox==".")
567     {
568        blackbox = Current()->GetPrototype();
569     }
570     else
571     {
572        blackbox = Current()->GetPrototype()->bbFindBlackBox(nameblackbox);
573     }
574     
575     std::string page;
576
577     if (blackbox)
578       {      
579         // Don't pollute the file store with  "temp_dir" directories ...
580         std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
581         char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
582
583         std::string directory = default_doc_dir; 
584         if (c != '/' && c !='\\') directory = directory + "/";
585
586         directory = directory +  "temp_dir";
587         //std::string directory("temp_dir");
588         std::string filename(directory + "/" + "bbtk_graph_pipeline");
589         std::string filename_html(filename+".html");
590         std::string command0("mkdir \""+directory + "\"");
591
592 #if defined(_WIN32)
593         std::string command2("start ");
594 #else 
595         std::string command2("gnome-open ");
596 #endif
597
598         command2=command2+filename_html;
599         page = filename_html;
600         // 1. Generate Html Diagram
601         std::ofstream s;
602         s.open(filename_html.c_str());
603         if (s.good()) 
604           {
605             s << "<html><head><title>BBtk graph diagram</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"></head>\n";
606             s << "<body bgcolor=\"#FFFFFF\" text=\"#000000\"> \n\n";
607             if ( blackbox->bbGetName()=="workspacePrototype" )
608               {
609                 s << "<center>Current workspace</center>";
610               } else {
611               s << "<center>" << blackbox->bbGetName()<< "</center>";
612             } 
613
614             blackbox->bbInsertHTMLGraph( s, detail, level, true, directory, false );
615             s << "</body></html>\n";
616           }
617         s.close();
618         
619         // 2. Starting Browser
620         if (system_display) system( command2.c_str() );      
621       } 
622     else 
623       {
624         bbtkMessageInc("Help",1,"No black box: \""
625                        <<nameblackbox<<"\" " <<std::endl);
626       }
627     return page;
628   }
629   //=======================================================================
630
631   //=======================================================================
632   void Executer::ShowRelations(const std::string &nameblackbox, 
633                                const std::string &detailStr, 
634                                const std::string &levelStr)
635   {
636     bool found=false;
637     
638     int detail = atoi(detailStr.c_str());
639     int level  = atoi(levelStr.c_str());
640     BlackBox::Pointer blackbox;
641     if (nameblackbox.compare(".")==0)
642       {
643         blackbox=Current()->GetPrototype();
644       } 
645     else 
646       {
647         blackbox = Current()->GetPrototype()->bbFindBlackBox(nameblackbox);
648       }
649     
650     if (blackbox)
651       {
652         found=true;
653         blackbox->bbShowRelations(blackbox,detail,level); //,mFactory);
654       }
655     
656     if (!found) 
657       {
658         bbtkError("Blackbox Name not found.. <"  <<nameblackbox<<">");
659       }
660   }
661   //=======================================================================
662
663   //=======================================================================
664   /// sets the level of message
665   void Executer::SetMessageLevel(const std::string &kind,
666                                  int level)
667   {
668     bbtk::MessageManager::SetMessageLevel(kind,level);
669   }
670   //=======================================================================
671
672   //=======================================================================
673   /// Prints help on the messages
674   void  Executer::HelpMessages()
675   {
676     bbtk::MessageManager::PrintInfo();
677   }
678   //=======================================================================
679
680   //=======================================================================
681   ///
682   void Executer::Print(const std::string &str)
683   {  
684     if (GetNoExecMode() &&  (Current()==GetWorkspace()) ) return;
685     if (Current()!=GetWorkspace()) return;
686
687     bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
688
689  // TO DO :
690  // InterpretLine ("load std")
691  // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande 
692  // InterpretLine("new Print _P_") 
693  // InterpretLine("connect _C_.Out _P_.In")
694  // int num = 1
695  
696
697     std::vector<std::string> chains;
698     std::string delimiters("$");
699
700     // Skip delimiters at beginning.
701     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
702     bool is_text = true;
703     if (lastPos>0) is_text = false;
704
705     // Find first delimiter.
706     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
707
708     while (std::string::npos != pos || std::string::npos != lastPos)
709     {
710        if (is_text) 
711        {
712           // Found a text token, add it to the vector.
713           chains.push_back(str.substr(lastPos, pos - lastPos));
714  // std::string token = str.substr(lastPos, pos - lastPos)
715  // InterpretLine("set _C_.In%num% %token%")
716  
717        }
718        else 
719        {
720
721        // is an output (between $$) : decode 
722          std::string tok,box,output;
723          tok = str.substr(lastPos, pos - lastPos);
724          Utilities::SplitAroundFirstDot(tok,box,output);
725          chains.push_back( Get(box,output) );
726
727 // InterpretLine("connect %tok% _C_.In%num%") 
728
729        }
730         // Skip delimiters.  Note the "not_of"
731        lastPos = str.find_first_not_of(delimiters, pos);
732         // Find next delimiter
733        pos = str.find_first_of(delimiters, lastPos);
734     //
735        is_text = !is_text;
736 // num ++;
737      }
738 // InterpretLine("exec _P_")
739 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
740
741     std::vector<std::string>::iterator i;
742     for (i= chains.begin(); i!=chains.end(); ++i) 
743       {
744         //  bbtkMessage("Echo",1,*i);
745         Utilities::SubsBackslashN(*i);
746         bbtkMessage("Output",1,*i);
747       }
748     bbtkMessage("Output",1,std::endl);
749   }
750   //==========================================================================
751
752   //==========================================================================
753   std::string Executer::GetObjectName() const
754   {
755     return std::string("Executer");
756   }
757   //==========================================================================
758   
759   //==========================================================================
760   std::string  Executer::GetObjectInfo() const 
761   {
762     std::stringstream i;
763     return i.str();
764   }
765   //==========================================================================
766   //==========================================================================
767 size_t  Executer::GetObjectSize() const 
768 {
769   size_t s = Superclass::GetObjectSize();
770   s += Executer::GetObjectInternalSize();
771   return s;
772   }
773   //==========================================================================
774   //==========================================================================
775 size_t  Executer::GetObjectInternalSize() const 
776 {
777   size_t s = sizeof(Executer);
778   return s;
779   }
780   //==========================================================================
781   //==========================================================================
782   size_t  Executer::GetObjectRecursiveSize() const 
783   {
784     size_t s = Superclass::GetObjectRecursiveSize();
785     s += Executer::GetObjectInternalSize();
786     s += mFactory->GetObjectRecursiveSize();
787     return s;
788   }
789   //==========================================================================
790 }//namespace