Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/Framework/src/APPFramework.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: APPFramework.cc,v 1.97 2002/08/19 19:32:10 desilva Exp $
00004 //
00005 // Description:
00006 //      Class APPFramework. This is the overall framework for the BaBar
00007 //      analysis framework. It controls the creation of sequences and
00008 //      paths and the processing of events.
00009 //
00010 // Environment:
00011 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00012 //
00013 // Author List:
00014 //      David R. Quarrie                Original Author
00015 //      Marc Turcotte                   Introduced Actions '97
00016 //                                      Removed dependency on DbiEvent 6/97
00017 //                                      Enabled/modified other entry  12/97
00018 //                                      Modified for new style begin/end 2/98
00019 //      Marc Turcotte                   Added new style event 2/23
00020 //      Marc Turcotte                   Added Dynamic Dispatch support 3/98
00021 //                                      This work is done in collaboration
00022 //                                      with CLEO.
00023 //      Marc Turcotte                   Introduced AppStopType 3/20/98
00024 //      Marc Turcotte                   Let zero frame thru frame()
00025 //                                      so that null goes to module
00026 //                                      which can have overriden the
00027 //                                      frame() function and be a
00028 //                                      provider instead of a consumer 4/8/98
00029 //      Marc Turcotte                   Introduced ActionControllers 4/14/98
00030 //      Marc Turcotte                   Introduced static _theFrame init 
00031 //                                      4/30/98
00032 //      Marc Turcotte                   Introduced static _theAbsEvent init
00033 //                                      but /* */ it for migration 4/30/98
00034 //      Marc Turcotte                   Introduced theEvent() & zeroTheEvent()
00035 //                                      4/30/98
00036 //      Marc Turcotte                   Merged in R.Kapur's TK interface 5/98
00037 //      Marc Turcotte                   Added _TkInterface init 6/18/98
00038 //      Marc Turcotte                   Modified for AppResult 6/19/98
00039 //      Marc Turcotte                   Added theDispatchStopType to
00040 //                                      signatures 6/23/98
00041 //      Marc Turcotte                   Changed AppResult for AppResult 6/23/98
00042 //      Marc Turcotte                   Changed for new AbsEvent sigs 6/24/98
00043 //      Marc Turcotte                   Migrated setupTheApp from APPMain 
00044 //                                      7/28/98
00045 //      Marc Turcotte                   Introduced non const heap temporaries
00046 //                                      moduleName, pathName and execName 
00047 //                                      copied into for safety reasons. 7/30/98
00048 //      Marc Turcotte                   Added arg list to setupTheApp 8/6/98
00049 //      Marc Turcotte                   Removed call to other(...) from
00050 //                                      continueHandler(...) 9/23/98
00051 //      A. De Silva                     Actions made to work on input & output
00052 //                                      modules. 6/24/99
00053 //
00054 // Copyright Information:
00055 //      Copyright (C) 1994, 1995        Lawrence Berkeley Laboratory
00056 //      Copyright (C) 1997, 1998        University of Texas at Dallas
00057 //
00058 //------------------------------------------------------------------------
00059 #include "Experiment/Experiment.hh"
00060 
00061 //-------------------------------
00062 // Collaborating Class Headers --
00063 //-------------------------------
00064 #ifdef CDF
00065 #include "FrameUtil/AppActionTime.hh"
00066 #include "FrameUtil/AppActionHistoDir.hh"
00067 class AbsEvent;
00068 class AppRun;
00069 #else
00070 #include "Framework/AppAction.hh"
00071 #include "AbsEvent/AbsEvent.hh"
00072 #endif
00073 //-----------------------
00074 // This Class's Header --
00075 //-----------------------
00076 #include "Framework/APPFramework.hh"
00077 // note the above header now includes AbsCommandMemento.hh which in 
00078 // turn includes iostream.h.  Including iostream.h is a very heavy thing
00079 // to do and a consequence is that this APPFramework must be ordered after
00080 // the timer stuff. -LSK
00081 #include "Framework/APPExecNode.hh"
00082 #include "Framework/APPPath.hh"
00083 #include "Framework/APPSequence.hh"
00084 #include "Framework/APPInputModule.hh"
00085 #include "Framework/APPOutputModule.hh"
00086 #include "Framework/AppAccountModule.hh"
00087 #include "Framework/AppFileOutputModule.hh"
00088 #include "Framework/APPCommand.hh"
00089 #include "Framework/APPEventsCommand.hh"
00090 #include "Framework/APPModuleCommand.hh"
00091 #include "Framework/APPPathCommand.hh"
00092 #include "Framework/APPSequenceCommand.hh"
00093 #include "Framework/AppActionCommand.hh"
00094 #include "Framework/APPHash.hh"
00095 
00096 #include "Framework/APPJob.hh"
00097 #include "Framework/APPRun.hh"
00098 
00099 #ifdef CDF
00100 #include "AbsEnv/AbsEnv.hh"
00101 #endif
00102 
00103 #include "Framework/AppActionController.hh"
00104 
00105 #include "FrameUtil/APPList.hh"
00106 #include "FrameUtil/APPListIterator.hh"
00107 
00108 #include "FrameUtil/AbsInterp.hh"
00109 
00110 //-------------
00111 // C Headers --
00112 //-------------
00113 #include <assert.h>
00114 #include <stddef.h>
00115 #include <stdio.h>
00116 #include <string.h>
00117 #include <strstream.h>
00118 
00119 //---------------
00120 // C++ Headers --
00121 //---------------
00122 #include <iostream.h>
00123 
00124 #ifndef CDF
00125 #include "CommonUtils/ComPathNameSearch.hh"
00126 #include "CommonUtils/ComTimeStamp.hh"
00127 #endif
00128 
00129 //-----------------------------------------------------------------------
00130 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00131 //-----------------------------------------------------------------------
00132 
00133 
00134 //              ----------------------------------------
00135 //              -- Public Function Member Definitions --
00136 //              ----------------------------------------
00137 
00138 //-----------------------
00139 // Static Initializers --
00140 //-----------------------
00141 
00142 AppFrame*   AppFramework::_theFrame              = 0;
00143 AppStopType AppFramework::_theDispatchStopType   = AppStopType::never_assigned;
00144 
00145 /******************************************************
00146 
00147 Migration code of 4/30/98 is ready below:
00148 
00149 AbsEvent* AppFramework::_theAbsEvent             = 0;
00150 
00151 *******************************************************/
00152 
00153 //----------------
00154 // Constructors --
00155 //----------------
00156 
00157 AppFramework::AppFramework( int argc, char* argv[] )
00158 #ifdef CDF
00159     : APPNoCloneModule( "Framework/AC++", "Application Framework" ),
00160 #else
00161     : APPNoCloneModule( "AppFrame", "Application Framework" ),
00162 #endif
00163       _exitRequested  ( false ),
00164       _theOutputModule( 0 ),
00165       _isBegun        ( false ),
00166       _indentLevel    ( 0 ),
00167       _maxNameLength  ( 0 ),
00168       _argc           ( argc ),
00169       _argv           ( argv ),
00170       _stopRequested  ( false ),
00171       _eventsCmd( "events"  , this ),
00172       _moduleCmd( "module"  , this ),
00173       _pathCmd( "path"    , this ),
00174       _sequenceCmd( "sequence", this ),
00175       _configCmd( "config"     , this ),
00176       _actionCmd("action",this),
00177       _theAccountModule(0)
00178   {
00179 
00180     _execType        = APP_framework;
00181     setFramework ( this );
00182 
00183     _executables     = new APPHash< APPExecutable >;
00184 
00185     _execNodes       = new APPList< APPExecNode* >;
00186     _modules         = new APPList< AppModule* >;
00187     _paths           = new APPList< APPPath* >;
00188     _sequences       = new APPList< APPSequence* >;
00189     _cloneList       = new APPList< AppCloneRecorder *>;
00190   
00191     _inputModules    = new APPList< APPInputModule* >;
00192     _outputModules   = new APPList< APPOutputModule* >;
00193     _accountModules    = new APPList< AppAccountModule* >;
00194 
00195     _localInputModule = _theInputModule  =
00196     new APPInputModule("DummyInput","dummy input module");
00197 
00198     add( _theInputModule );
00199 
00200     _localOutputModule = _theOutputModule = new AppFileOutputModule;
00201     add( _theOutputModule );
00202 
00203     _defaultPath = new APPPath( "AllPath", "Default (all modules) path" );
00204     _defaultPath->setEnabled( false );
00205     add( _defaultPath );
00206 
00207 #ifdef CDF
00208     setPrompt( "AC++> " );
00209 #else
00210     setPrompt( "> " );
00211 #endif
00212     commands( )->append(&_eventsCmd);
00213     commands( )->append(&_moduleCmd);
00214     commands( )->append(&_pathCmd);
00215     commands( )->append(&_sequenceCmd);
00216     commands( )->append(&_configCmd);
00217     commands( )->append(&_actionCmd);
00218 
00219     _actions = new APPList<AppAction*>; // Holds the list of Actions
00220     _theActionControllers = new APPList<AppActionController*>;
00221 
00222     // Grab bag of AppMethods. This is not the Module hash table...
00223     _theAppMethodsGrabBag =  new APPList<AppMethodBase*>;
00224 
00225     // Create an Abstract Interpreter by calling it's class static
00226     // instance method.  The AbsInterp follows an extension of the
00227     // singleton pattern.  Note that class statics are similar to globals
00228     // in that one can gain access to the single instance from anywhere in
00229     // the program by calling AbsInterp::theInterpreter( ).
00230     AbsInterp* interp = AbsInterp::theInterpreter( );
00231 
00232 #ifdef CDF
00233     // The AbsEnv is now also a singleton, but for backward compatibility
00234     // we will maintain the global pointer to it, for a bit longer...
00235     gblEnv = AbsEnv::theAbsEnv( );
00236 #endif
00237 }
00238 
00239 //--------------
00240 // Destructor --
00241 //--------------
00242 
00243 AppFramework::~AppFramework( )
00244 {
00245     delete _executables;
00246 
00247     APPListDeleteAll(*_execNodes);
00248     delete _execNodes;
00249 
00250     APPListDeleteAll(*_modules, this, "module");
00251     delete _modules;
00252 
00253     APPListDeleteAll(*_paths, this, "path");
00254     delete _paths;
00255 
00256     APPListDeleteAll(*_sequences, this, "sequence");
00257     delete _sequences;
00258 
00259     APPListDeleteAll(*_inputModules, this, "input module");
00260     delete _inputModules;
00261 
00262     APPListDeleteAll(*_outputModules, this, "output module");
00263     delete _outputModules;
00264 
00265     APPListDeleteAll(*_accountModules, this, "account module");
00266     delete _accountModules;
00267 
00268     APPListDeleteAll(*_actions, this, "action");
00269     delete _actions;
00270 
00271     APPListDeleteAll(*_theActionControllers);
00272     delete _theActionControllers;
00273 
00274     APPListDeleteAll(*_theAppMethodsGrabBag);
00275     delete _theAppMethodsGrabBag;
00276     
00277     APPListDeleteAll(*_cloneList);
00278     delete _cloneList;
00279 
00280     // Delete the singletons:
00281 #ifdef CDF
00282     delete AbsEnv::theAbsEnv( );
00283 #endif
00284     delete AbsInterp::theInterpreter( );
00285 
00286 }
00287 
00288 //--------------
00289 // Operations --
00290 //---------------
00291 
00292 AbsEvent*
00293 AppFramework::theEvent() const { return _theAbsEvent; }
00294 
00295 void AppFramework::zeroTheEvent() {
00296   if (0 != _theAbsEvent) {
00297     delete _theAbsEvent;
00298     _theAbsEvent=0;
00299   }
00300 }
00301 
00302 AppResult
00303 AppFramework::beginJob( AbsEvent* anEvent )
00304 {
00305     AppModule** mod;
00306     AbsEvent* nullEvent = 0;
00307 
00308   // Build a list with Input, Output and App Modules all stored
00309   // as AppModules (common base class)
00310 
00311   APPList<AppModule*> allAsModules;
00312   buildModuleList( allAsModules, *inputModules() );
00313   buildModuleList( allAsModules, *outputModules() );
00314   buildModuleList( allAsModules, *modules() );
00315   buildModuleList( allAsModules, *accountModules() );
00316 
00317   // Now use that list to give beginJob to those modules
00318 
00319   APPListIterator<AppModule*> iter1( allAsModules );
00320   APPListIterator<AppActionController*> itr(*actionControllers());
00321   while ( mod = (AppModule**)iter1( ) ) {
00322     if ( (*mod)->isEnabled( ) && ! (*mod)->isInitialized( ) ) {
00323       AppActionController** anActionController;
00324       itr.rewind();
00325       while ( anActionController=itr.next() ) {                    
00326         (*anActionController)->beforeBeginJob(*mod,anEvent);
00327       }
00328       (*mod)->beginJob( anEvent );
00329       (*mod)->setInitialized( );
00330       itr.rewind();
00331       while ( anActionController=itr.next() ) {
00332         (*anActionController)->afterBeginJob(*mod,anEvent);
00333       }
00334     }
00335   }
00336   
00337   if ( 0 != theInputModule( ) ) {
00338     theInputModule( )->beginRun( nullEvent );
00339   }
00340   if ( 0 != theOutputModule( ) && theOutputModule()->isEnabled()) {
00341     theOutputModule( )->beginRun( nullEvent );
00342   }
00343   
00344   return AppResult::OK;
00345   
00346 }
00347 
00348 AppResult
00349 AppFramework::beginRun( AbsEvent* anEvent )
00350 {
00351   AppModule** mod;
00352 
00353   // Build a list with Input, Output and App Modules all stored
00354   // as AppModules (common base class)
00355   APPList<AppModule*> allAsModules;
00356   buildModuleList( allAsModules, *inputModules() );
00357   buildModuleList( allAsModules, *modules() );
00358   buildModuleList( allAsModules, *outputModules() );
00359   buildModuleList( allAsModules, *accountModules() );
00360 
00361   // Now use that list to give beginRun to those modules
00362 
00363   APPListIterator<AppModule*> iter1( allAsModules );
00364   APPListIterator<AppActionController*> itr(*actionControllers());
00365   while ( mod = (AppModule**)iter1( ) ) {
00366     if ( (*mod)->isEnabled( ) ) {
00367       AppActionController** anActionController;
00368       itr.rewind();
00369       while ( anActionController=itr.next() ) {
00370         (*anActionController)->beforeBeginRun(*mod,anEvent);
00371       }
00372       (*mod)->beginRun( anEvent );
00373       itr.rewind();
00374       while ( anActionController=itr.next() ) {
00375         (*anActionController)->afterBeginRun(*mod,anEvent);
00376       }
00377     }
00378   }
00379 
00380   return AppResult::OK;
00381   
00382 }
00383 
00384 AppResult
00385 AppFramework::frame( AppFrame* aFrame,
00386                      const AppStopType& theDispatchStopType ) { // Dynamic dispatch
00387 
00388   APPPath** path;
00389 
00390   resetNodes( );          // This will do all the nodes "again" but _no_ standard member functions
00391                           // will be called; the user is expected to NOT bind those... Beware...
00392   resetAppMethods(false); // Reset the AppMethods for this event
00393 
00394   APPListIterator<APPPath*> theIterator( *paths( ) );
00395   AppResult theResult = AppResult::OK;
00396   while ( path = theIterator( ) ) {
00397     if ( (*path)->isEnabled( ) ) {
00398       theResult=(*path)->frame( aFrame, theDispatchStopType );
00399     }
00400   }
00401 
00402   return theResult.value();
00403 
00404 }
00405 
00406 AppResult
00407 AppFramework::accountEvent(AbsEvent*& theEvent)
00408 {
00409   if ( 0 != theAccountModule( )  && theAccountModule()->isEnabled() ) {
00410     APPListIterator<AppActionController*> itr1( *actionControllers() );
00411     AppActionController** anActionController;
00412     while ( anActionController=itr1.next() ) {
00413       (*anActionController)->beforeEvent(theAccountModule(),theEvent);
00414     }
00415     itr1.rewind();
00416     theAccountModule( )->accountEvent( theEvent );
00417     while ( anActionController=itr1.next() ) {
00418       (*anActionController)->afterEvent(theAccountModule(),theEvent);
00419     }
00420   }
00421   return AppResult::OK;
00422 }
00423 
00424 
00425 AppResult
00426 AppFramework::outputEvent(AbsEvent* theEvent)
00427 {
00428   if ( 0 != theOutputModule( )  && theOutputModule()->isEnabled() )    {
00429     APPListIterator<AppActionController*> itr1( *actionControllers() );
00430     AppActionController** anActionController;
00431     while ( anActionController=itr1.next() ) {
00432       (*anActionController)->beforeEvent(theOutputModule(),theEvent);
00433     }
00434     itr1.rewind();
00435     theOutputModule( )->outputEvent( theEvent );
00436     while ( anActionController=itr1.next() ) {
00437       (*anActionController)->afterEvent(theOutputModule(),theEvent);
00438     }
00439   }
00440   return AppResult::OK;
00441 }
00442 
00443 AppResult
00444 AppFramework::event( AbsEvent* anEvent )
00445 {
00446     APPPath** path;
00447 
00448     assert ( 0 != anEvent );
00449 
00450     resetNodes( );
00451 
00452     APPListIterator<APPPath*> theIterator( *paths( ) );
00453     while ( path = theIterator( ) ) {
00454                 if ( (*path)->isEnabled( ) ) {
00455                         (*path)->event( anEvent );
00456                 }
00457     }
00458     return AppResult::OK;
00459 }
00460 
00461 AppResult
00462 AppFramework::other( AbsEvent* anOther )
00463 {
00464 
00465 // As per request of Online, make "other run like path" meaning
00466 // that Framework::other(AbsEvent*) should act like
00467 // Framework::event(AbsEvent*) and not be called on disabled modules
00468 // and be called in "path order". M. Turcotte 12/2/97
00469 // This "other" deal will be phased out in favor of
00470 // frames. 6/25/98
00471 
00472 
00473     APPPath** path;
00474     assert ( 0 != anOther );
00475 
00476     resetNodes( );
00477     APPListIterator<APPPath*> theIterator( *paths( ) );
00478     while ( path = theIterator( ) ) {
00479                 if ( (*path)->isEnabled( ) ) {
00480                         (*path)->other( anOther ); // "other" processing...
00481                 }
00482     }
00483 
00484     return AppResult::OK;
00485 
00486 }
00487 
00488 AppResult
00489 AppFramework::endRun( AbsEvent* anEvent )
00490 {
00491   AppModule** mod;
00492   
00493   //  Assertion removed because of the use case when the user
00494   //  ends the run without beginning.
00495   //  M. Turcotte, UTDallas, 2/13/98
00496   //
00497   //    assert ( 0 != anEvent );
00498   
00499   // Build a list with Input, Output and App Modules all stored
00500   // as AppModules (common base class)
00501   APPList<AppModule*> allAsModules;
00502   buildModuleList( allAsModules, *modules() );
00503   buildModuleList( allAsModules, *inputModules() );
00504   buildModuleList( allAsModules, *outputModules() );
00505   buildModuleList( allAsModules, *accountModules() );
00506   
00507   // Now use that list to give endRun to those modules
00508 
00509   APPListIterator<AppModule*> theIterator( allAsModules );
00510   APPListIterator<AppActionController*> itr(*actionControllers());
00511   while ( mod = theIterator( ) ) {
00512     if ( (*mod)->isEnabled( ) && (*mod)->isInitialized( ) ) {      
00513       AppActionController** anActionController;      
00514       itr.rewind();
00515       while ( anActionController=itr.next() ) {
00516         (*anActionController)->beforeEndRun(*mod,anEvent);
00517       }
00518       (*mod)->endRun( anEvent );      
00519       itr.rewind();
00520       while ( anActionController=itr.next() ) {
00521         (*anActionController)->afterEndRun(*mod,anEvent);
00522       }
00523     }
00524   }   
00525   return AppResult::OK;
00526 
00527 }
00528 
00529 AppResult
00530 AppFramework::endJob( AbsEvent* anEvent )
00531 {
00532   AppModule** mod;
00533 
00534  //   This assertion had to be removed because of the use
00535  //   case when the use just starts up the framework and
00536  //   then quits without begining...
00537  //   M. Turcotte, UTDallas, 2/13/98
00538  //
00539  //   assert ( 0 != anEvent );  
00540 
00541   // Build a list with Input, Output and App Modules all stored
00542   // as AppModules (common base class)
00543   APPList<AppModule*> allAsModules;
00544   buildModuleList( allAsModules, *modules() );
00545   buildModuleList( allAsModules, *inputModules() );
00546   buildModuleList( allAsModules, *outputModules() );
00547   buildModuleList( allAsModules, *accountModules() );
00548 
00549   // Now use that list to give beginJob to those modules
00550 
00551   APPListIterator<AppModule*> theIterator( allAsModules );
00552   APPListIterator<AppActionController*> itr(*actionControllers());
00553   while ( mod = theIterator( ) ) {
00554     if ( (*mod)->isEnabled( ) && (*mod)->isInitialized( ) ) {     
00555       AppActionController** anActionController;      
00556       itr.rewind();
00557       while ( anActionController=itr.next() ) {
00558         (*anActionController)->beforeEndJob(*mod,anEvent);
00559       }
00560       (*mod)->endJob( anEvent );
00561       itr.rewind();
00562       while ( anActionController=itr.next() ) {
00563         (*anActionController)->afterEndJob(*mod,anEvent);
00564       }
00565     }   
00566   }
00567 
00568   return AppResult::OK;
00569   
00570 }
00571 
00572 AppResult
00573 AppFramework::abortJob( AbsEvent* anEvent )
00574 {
00575     AppModule** mod;
00576 
00577 //  Assertion removed because of a use case when the
00578 //  user aborts without beginning...
00579 //  M. Turcotte, UTDallas, 2/13/98
00580 //
00581 //    assert ( 0 != anEvent );
00582 
00583     APPListIterator<AppModule*> theIterator( *modules( ) );
00584     while ( mod = theIterator( ) ) {
00585                 if ( (*mod)->isEnabled( ) && (*mod)->isInitialized( ) ) {
00586                         (*mod)->abortJob( anEvent );
00587                 }
00588     }
00589     if ( 0 != theOutputModule( ) && theOutputModule()->isEnabled() ) {
00590                 theOutputModule( )->abortJob( anEvent );
00591     }
00592 
00593     return AppResult::OK;
00594 
00595 }
00596 
00597 void
00598 AppFramework::talkTo( )
00599 {
00600   AbsInterp* interp = AbsInterp::theInterpreter( );
00601   assert( interp->isInitialized( ) );
00602   
00603 #ifndef CDF
00604   interp->runCommandFile((const char*) 
00605                ComPathNameSearch("Framework/Framework/BaBar_FrameworkRc.tcl"));
00606 #endif
00607   
00608   _exitRequested = false;
00609   enableCommands( );
00610   
00611   
00612   if ( 2 <= _argc )
00613     {
00614       interp->runCommandFile( _argv[1] );
00615     }
00616   
00617   while ( ! _exitRequested )
00618     {
00619       interp->startInterpLoop( );
00620     }
00621 #ifdef CDF
00622   endJob( AbsEnv::theJobRecord( ) );
00623 #else
00624   // We cannot do this in BaBar since (from gpdf)
00625   // OEP and OPR jobs do all their event processing after talkTo()
00626   // endJob( _theAbsEvent );
00627 #endif
00628   disableCommands( );
00629 
00630 }
00631 
00632 void
00633 AppFramework::help( int argc, char** argv )
00634 {
00635    AppModule::help( argc, argv );
00636    if ( argc == 1 )
00637    {
00638       fullReport("");
00639       fullReport( "For more information on a particular command type '<command> help'." );
00640       fullReport( "A minimal set to select an input file and run 5 events is:");
00641       fullReport( "    module talk FileInput");
00642       fullReport( "      input file <your_file>");
00643       fullReport( "      exit");
00644       fullReport( "    ev begin -nev 5");
00645       fullReport( "    exit");
00646       fullReport("");
00647       fullReport("A script can also be specified as the first argument when running the program.");
00648       fullReport("");
00649       fullReport( "In addition the following command aliases can also be used." );
00650       fullReport( "" );
00651       fullReport( "Alias: Command Equivalent:" );
00652       AbsInterp* interp = AbsInterp::theInterpreter( );
00653       interp->simulateInput( "alias" );
00654    }
00655 }
00656 
00657 void
00658 AppFramework::show( int argc, char** argv ) const
00659 {
00660    AbsInterp* interp = AbsInterp::theInterpreter( );
00661    FwkString argStr;
00662    if ( argc > 1 )
00663    {
00664       argStr = argv[1];  // Just use first arg.
00665    }
00666    else
00667    {
00668       argStr = " ";      // No args means show everything
00669    }
00670    if (( argc == 1 ) || (argStr == "module"))
00671    {
00672       fullReport   ( "**** Listing of all available modules ****" );
00673       fullReport   ( " " );
00674       interp->simulateInput( "module list" );
00675    }
00676    if (( argc == 1 ) || (argStr == "path"))
00677    {
00678       fullReport   ( " " );
00679       fullReport   ( "**** Listing of all defined paths ****" );
00680       fullReport   ( " " );
00681       interp->simulateInput( "path list" );
00682    }
00683    if (( argc == 1 ) || (argStr == "par"))
00684      {
00685        fullReport   ( " " );
00686        fullReport   ( "**** Current value of items in the Framework ****");
00687        fullReport   ( " " );
00688        APPCommand** command;
00689        APPListIterator<APPCommand*> theIterator( *commands( ) );
00690        while ( command = theIterator( ) ) {     
00691          if ( (*command)->isShowable( ) ) {        
00692            partialReport( "      " );
00693            (*command)->show( );
00694          }
00695        }      
00696      }
00697    if (( argc == 1 ) || (argStr == "timer"))
00698    {
00699       APPListIterator<AppAction*> iter( *actions( ) );
00700       AppAction** anAction;
00701       while ( anAction=iter( ) )
00702       {  // The Framework timer action is defualt constructed with this name
00703          if ( (*anAction)->name( ) == "Timer Action" )
00704          {
00705             if ( argc == 1 )
00706             {
00707                (*anAction)->report( false );
00708             }
00709             else
00710             {
00711                (*anAction)->report( true );
00712             }
00713          }
00714       }
00715    }
00716 }
00717 
00718 void
00719 AppFramework::exit( )
00720 {
00721     _exitRequested = true;
00722     AbsInterp* interp = AbsInterp::theInterpreter( );
00723     interp->setDoLoopInterp(false);   // terminate interpreter loop
00724 }
00725 
00726 void
00727 AppFramework::beginHandler( int nEvents )
00728 {
00729   if (0 != _theAbsEvent) {
00730     delete _theAbsEvent;
00731     _theAbsEvent         = 0;
00732   }
00733   _theFrame            = 0;
00734   _theDispatchStopType = AppStopType::never_assigned;
00735 
00736 //-----------------------------------------------------------------------
00737 //  This code will not work (for events) until we change the logic of input modules
00738 //  and putting it in would require moving the input call in the main event loop to
00739 //  _after_ the walk and output calls. But if this could be done, it would allow having
00740 //  an event or frame in hand to be handed over to beginJob.
00741 //
00742 //    if ( 0 != theInputModule() ) {
00743 //      if ( _enableFrames.value() ) {
00744 //        AppResult theResult = theInputModule()->inputFrame( _theFrame, _theDispatchStopType ); // Get a frame in...
00745 //      } else {
00746 //        AppResult theResult = theInputModule()->inputEvent( _theAbsEvent );                    // Get an event in...
00747 //      }
00748 //    }
00749 //-----------------------------------------------------------------------
00750 
00751 #ifdef CDF
00752     beginJob( AbsEnv::initJobRecord( ) );
00753 #else
00754     beginJob( _theAbsEvent );
00755 #endif
00756     _isBegun = true;
00757 
00758     continueHandler( nEvents );
00759 }
00760 
00761 void
00762 AppFramework::continueHandler( int nEvents )
00763 {
00764 
00765   int number=0;
00766   int numberOfFrames=0;
00767   
00768   if ( ! _isBegun ) {    
00769     if (0 != _theAbsEvent) {
00770       delete _theAbsEvent;
00771       _theAbsEvent = 0;
00772     }
00773     _theFrame    = 0;
00774     _theDispatchStopType = AppStopType::never_assigned;
00775     
00776 //**********************************************************************************************************************
00777 //  This code will not work until we change the logic of input modules in BaBar
00778 //  and putting it in would require moving the input call in the main event loop to
00779 //  _after_ the walk and output calls. But if this could be done, it would allow having
00780 //  an event or frame in hand to be handed over to beginJob.
00781 //
00782 //      _theAbsEvent         = 0;
00783 //      _theFrame            = 0;
00784 //      _theDispatchStopType = AppStopType::never_assigned;
00785 //
00786 //      if ( 0 != theInputModule() ) {
00787 //
00788 //        if ( _enableFrames.value() ) {
00789 //          AppResult theResult = theInputModule()->inputFrame( _theFrame, _theDispatchStopType ); // Get Frame in...
00790 //          number++;
00791 //        } else {
00792 //          AppResult theResult = theInputModule()->inputEvent( _theAbsEvent );                    // Get an event in...
00793 //          number++;
00794 //        }
00795 //
00796 //      }
00797 //**********************************************************************************************************************
00798 
00799 #ifdef CDF
00800     beginJob( AbsEnv::initJobRecord( ) );
00801 #else
00802     beginJob( _theAbsEvent );
00803 #endif
00804     _isBegun = true;
00805 
00806   }
00807 
00808   _stopRequested = false;
00809 
00810   //
00811   // Move frames...
00812   //
00813   if ( _enableFrames.value() ) {
00814     
00815     numberOfFrames = 0;
00816     
00817     do {
00818       
00819       AppResult theResult = theInputModule()->inputFrame( _theFrame, _theDispatchStopType ); // Get a frame in...
00820       numberOfFrames++;
00821       
00822       if ( _theFrame!= 0 ) {
00823         theResult = frame( _theFrame, _theDispatchStopType );  // Walk frame...
00824         
00825         if(theResult.value()!=AppResult::OK) {
00826           fullReport("AppFramework:: Bad result code on return from a frame consumer: != OK");
00827                      }                            
00828           
00829         if ( 0 != theOutputModule( ) && theOutputModule()->isEnabled() ) {
00830           theOutputModule( )->outputFrame( _theFrame );                                      // Push the frame out...
00831         }
00832       }
00833       
00834     } while ( ! _stopRequested && ( nEvents <= 0 || numberOfFrames < nEvents ) );
00835     
00836   }
00837 
00838   //
00839   //  Move standard AbsEvent
00840   //
00841   
00842   if ( 0 != theInputModule( ) && !_enableFrames.value() ) {
00843     
00844     number = 0;
00845     
00846     AppActionController** anActionController;
00847     APPListIterator<AppActionController*> 
00848       itr1( *actionControllers() );
00849     APPListIterator<AppActionController*> 
00850       itr2( *actionControllers() );
00851     
00852     do {
00853       
00854       while ( anActionController=itr1.next() ) {
00855         (*anActionController)->beforeEvent(theInputModule(),_theAbsEvent);
00856       }
00857       itr1.rewind();
00858       AppResult theResult = theInputModule( )->inputEvent( _theAbsEvent,
00859                                                            _theDispatchStopType );      
00860       while ( anActionController=itr1.next() ) {
00861         (*anActionController)->afterEvent(theInputModule(),_theAbsEvent);
00862       }
00863       itr1.rewind();
00864       
00865       if ( 0 != _theAbsEvent ) {
00866         
00867         //
00868         // Handle the traditional dispatch here
00869         //
00870         
00871         if ( _theDispatchStopType == AppStopType::physics_event ) {
00872           event( _theAbsEvent );
00873           number++;
00874         } else if ( _theDispatchStopType == AppStopType::begin_run ) {
00875           //  Begin Run
00876           beginRun( _theAbsEvent );
00877           
00878         } else if ( _theDispatchStopType == AppStopType::end_run ) {
00879           //  End Run
00880           endRun( _theAbsEvent );
00881           
00882         } else {
00883           //  Other record type
00884           other( _theAbsEvent );
00885         }
00886         outputEvent(_theAbsEvent);
00887         accountEvent(_theAbsEvent);
00888       }
00889     }
00890     while ( ! _stopRequested && 0 != _theAbsEvent &&
00891             ( nEvents <= 0 || number < nEvents )      );
00892     
00893     if ( 0 == _theAbsEvent ) {
00894       _isBegun = false;
00895     }
00896     
00897   }
00898 }
00899 
00900 void
00901 AppFramework::resetIndent( )
00902 {
00903     _indentLevel = 0;
00904 }
00905 
00906 void
00907 AppFramework::increaseIndent( )
00908 {
00909     _indentLevel++;
00910 }
00911 
00912 void
00913 AppFramework::decreaseIndent( )
00914 {
00915     if ( _indentLevel > 0 ) {
00916         _indentLevel--;
00917     }
00918 }
00919 
00920 void
00921 AppFramework::skipToIndent( )
00922 {
00923   int i;
00924 
00925     for ( i = 0; i < _indentLevel; i++ ) {
00926                 partialReport("    ");
00927     }
00928 }
00929 
00930 void
00931 AppFramework::printName( const char* const theName, int mode )
00932 {
00933   size_t i;
00934   size_t len;
00935   
00936   partialReport(theName);
00937   len = strlen( theName );
00938   if ( 0 != mode ) {
00939     ostrstream bufstream;
00940     bufstream << mode << '\0';
00941     partialReport(" (");
00942     char* bufptr = bufstream.str();
00943     partialReport(bufptr);
00944     partialReport(")");
00945     len = len + 4;
00946     delete [] bufptr;  // str() freezes underlying array
00947   }
00948   for ( i = len - 4; i < _maxNameLength; i++ ) {
00949     partialReport(" ");
00950   }
00951 }
00952 
00953 //-------------
00954 // Selectors --
00955 //-------------
00956 
00957 APPExecutable*
00958 AppFramework::fetch( const char* const aName ) const
00959 {
00960 
00961     assert ( 0 != aName );
00962 
00963     return _executables->fetch( aName );
00964 }
00965 
00966 AppModule*
00967 AppFramework::fetchModule( const char* const aName ) const
00968 {
00969     APPExecutable* anExec;
00970     APPExecutable* theExec = 0;
00971 
00972     assert ( 0 != aName );
00973 
00974     if ( 0 != (anExec = _executables->fetch( aName ) )) {
00975       theExec = APPExecutable::narrow( anExec, APPExecutable::APP_module );
00976       if ( 0 == theExec ) {
00977         theExec = APPExecutable::narrow( anExec,
00978                                          APPExecutable::APP_filter );
00979       }
00980       if ( 0 == theExec ) {
00981         theExec = APPExecutable::narrow( anExec,
00982                                          APPExecutable::APP_input );
00983       }
00984       if ( 0 == theExec ) {
00985         theExec = APPExecutable::narrow( anExec,
00986                                          APPExecutable::APP_output );
00987       }
00988       if ( 0 == theExec ) {
00989         theExec = APPExecutable::narrow( anExec,
00990                                          APPExecutable::APP_account );
00991       }
00992     }
00993     return (AppModule*)theExec;
00994 }
00995 
00996 APPPath*
00997 AppFramework::fetchPath( const char* const aName ) const
00998 {
00999     APPExecutable* anExec;
01000 
01001     assert ( 0 != aName );
01002 
01003     if ( 0 != (anExec = _executables->fetch( aName ) )) {
01004         anExec = APPExecutable::narrow( anExec, APPExecutable::APP_path );
01005     }
01006     return (APPPath*)anExec;
01007 }
01008 
01009 APPSequence*
01010 AppFramework::fetchSequence( const char* const aName ) const
01011 {
01012     APPExecutable* anExec;
01013 
01014     assert ( 0 != aName );
01015 
01016     if ( 0 != (anExec = _executables->fetch( aName ) )) {
01017         anExec = APPExecutable::narrow( anExec, APPExecutable::APP_sequence );
01018     }
01019     return (APPSequence*)anExec;
01020 }
01021 
01022 bool
01023 AppFramework::has( const char* const aName ) const
01024 {
01025 
01026     assert ( 0 != aName );
01027 
01028     return ( _executables->has( aName ) );
01029 }
01030 
01031 bool
01032 AppFramework::hasModule( const char* const aName ) const
01033 {
01034     APPExecutable* anExec;
01035     APPExecutable* theExec = 0;
01036 
01037     assert ( 0 != aName );
01038 
01039     if ( 0 != (anExec = _executables->fetch( aName ) )) {
01040         theExec = APPExecutable::narrow( anExec, APPExecutable::APP_module );
01041                 if ( 0 == theExec ) {
01042                         theExec = APPExecutable::narrow( anExec,
01043                         APPExecutable::APP_filter );
01044                 }
01045     }
01046     return ( 0 != theExec );
01047 }
01048 
01049 bool
01050 AppFramework::hasPath( const char* const aName ) const
01051 {
01052     APPExecutable* anExec;
01053 
01054     assert ( 0 != aName );
01055 
01056     if ( 0 != (anExec = _executables->fetch( aName ) )) {
01057         anExec = APPExecutable::narrow( anExec, APPExecutable::APP_path );
01058     }
01059     return ( 0 != anExec );
01060 }
01061 
01062 bool
01063 AppFramework::hasSequence( const char* const aName ) const
01064 {
01065     APPExecutable* anExec;
01066 
01067     assert ( 0 != aName );
01068 
01069     if ( 0 != (anExec = _executables->fetch( aName ) )) {
01070         anExec = APPExecutable::narrow( anExec, APPExecutable::APP_sequence );
01071     }
01072     return ( 0 != anExec );
01073 }
01074 
01075 APPExecutable*
01076 AppFramework::execFromName( const char* const theName ) const
01077 {
01078     APPExecutable* theExec;
01079     theExec = fetchModule( theName );
01080     if ( 0 == theExec ) {
01081                 theExec = fetchSequence( theName );
01082     }
01083     return theExec;
01084 }
01085 
01086 //-------------
01087 // Modifiers --
01088 //-------------
01089 
01090 void
01091 AppFramework::setBegun( bool state )
01092 {
01093     _isBegun = state;
01094 }
01095 
01096 void
01097 AppFramework::setTheAccountModule (AppAccountModule* thatOne)
01098 {
01099   APPListIterator<AppAccountModule*> iter(*accountModules());
01100   AppAccountModule** aMod;
01101   while (aMod = iter()) {
01102     if (*aMod == thatOne) {
01103       _theAccountModule = thatOne;
01104       break;
01105     }
01106   }
01107 }
01108 
01109 bool
01110 AppFramework::setAccountModule( const char* const aName )
01111 {
01112   APPExecutable*  anExec;
01113   AppAccountModule* theAccount;
01114   bool result = false;
01115 
01116   if ( 0 != ( anExec = fetchModule( aName )) ) {
01117     if ( 0 != ( theAccount = (AppAccountModule*) 
01118                 APPExecutable::narrow( anExec, APPExecutable::APP_account ) ) )
01119       {
01120         if ( 0 != _theAccountModule ) {
01121           if ( _theAccountModule != theAccount ) {
01122             if ( _theAccountModule->isInitialized( ) ) {}
01123             _theAccountModule->setEnabled( false );
01124           }
01125         }
01126         _theAccountModule = theAccount;
01127         _theAccountModule->setEnabled( true );
01128         result = true;
01129       }
01130   }
01131   return result;
01132 }
01133 
01134 bool
01135 AppFramework::setInputModule( const char* const aName )
01136 {
01137     APPExecutable*  anExec;
01138     APPInputModule* theInput;
01139     bool result = false;
01140 
01141     if ( 0 != ( anExec = fetchModule( aName )) ) {
01142        if ( 0 != ( theInput = (APPInputModule*)APPExecutable::narrow( anExec,
01143                                                                       APPExecutable::APP_input ) ) ) 
01144        {
01145           if ( 0 != _theInputModule ) {
01146              if ( _theInputModule != theInput ) {
01147                 if ( _theInputModule->isInitialized( ) ) {}
01148                 _theInputModule->setEnabled( false );
01149              }
01150           }
01151           _theInputModule = theInput;
01152           _theInputModule->setEnabled( true );
01153           result = true;
01154        }
01155     }
01156     return result;
01157 }
01158 
01159 void
01160 AppFramework::setTheInputModule (APPInputModule* thatOne)
01161 {
01162   APPListIterator<APPInputModule*> iter(*inputModules());
01163   APPInputModule** aMod;
01164   while (aMod = iter()) {
01165     if (*aMod == thatOne) {
01166       _theInputModule = thatOne;
01167       break;
01168     }
01169   }
01170 }
01171 
01172 bool
01173 AppFramework::setOutputModule( const char* const aName )
01174 {
01175     APPExecutable*   anExec;
01176     APPOutputModule* theOutput;
01177     bool result = false;
01178 
01179     if ( 0 != ( anExec = fetchModule( aName )) ) {
01180        if ( 0 != ( theOutput = (APPOutputModule*)APPExecutable::narrow( anExec,
01181                                                                         APPExecutable::APP_output ) ) ) 
01182        {
01183           if ( 0 != _theOutputModule ) {
01184              if ( _theOutputModule != theOutput ) {
01185                 if ( _theOutputModule->isInitialized( ) ) {}
01186                 _theOutputModule->setEnabled( false );
01187              }
01188           }
01189           _theOutputModule = theOutput;
01190           _theOutputModule->setEnabled( true );
01191           result = true;
01192        }
01193     }
01194     return result;
01195 }
01196 
01197 void
01198 AppFramework::add( const APPExecNode* const aNode )
01199 {
01200 
01201     assert ( 0 != aNode );
01202 
01203     _execNodes->append( (APPExecNode*)aNode );
01204 }
01205 
01206 void
01207 /* !!!
01208    F_createTree( _theFileNode );
01209 */
01210 AppFramework::add( AppModule* const aModule )
01211 {
01212   
01213   assert ( 0 != aModule );
01214   
01215   if ( _executables->add( aModule->name( ), aModule ) ) {
01216     _modules->append( aModule );
01217     aModule->setFramework( this );
01218     if (_defaultPath != 0) _defaultPath->append( aModule );
01219     if ( strlen( aModule->name( ) ) > _maxNameLength ) {
01220       _maxNameLength = strlen( aModule->name( ) );
01221     }
01222   } else {
01223     if (verbose() ) {
01224       partialReport( "Module " );
01225       partialReport( aModule->name( ) );
01226       fullReport   ( " already exists" );
01227     }
01228     delete aModule;
01229   }
01230 }
01231 
01232 void
01233 AppFramework::add( AppAccountModule* const aModule )
01234 {
01235 
01236   assert ( 0 != aModule );
01237 
01238   if ( _executables->add( aModule->name( ), aModule ) ) {
01239     _accountModules->append( aModule );
01240     aModule->setFramework( this );
01241     if ( strlen( aModule->name( ) ) > _maxNameLength ) {
01242       _maxNameLength = strlen( aModule->name( ) );
01243     }
01244   } else {
01245     if (verbose() ) {
01246       partialReport( "Module " );
01247       partialReport( aModule->name( ) );
01248       fullReport   ( " already exists" );
01249     }
01250   }
01251 }
01252 
01253 void
01254 AppFramework::add( APPInputModule* const aModule )
01255 {
01256 
01257   assert ( 0 != aModule );
01258   
01259   if ( _executables->add( aModule->name( ), aModule ) ) {
01260     _inputModules->append( aModule );
01261     aModule->setFramework( this );
01262     if ( strlen( aModule->name( ) ) > _maxNameLength ) {
01263       _maxNameLength = strlen( aModule->name( ) );
01264     }
01265   } else {
01266     if (verbose() ) {
01267       partialReport( "Module " );
01268       partialReport( aModule->name( ) );
01269       fullReport   ( " already exists" );
01270     }
01271     delete aModule;
01272   }
01273 }
01274 
01275 void
01276 AppFramework::add( APPOutputModule* const aModule )
01277 {
01278   
01279   assert ( 0 != aModule );
01280   
01281   if ( _executables->add( aModule->name( ), aModule ) ) {
01282     _outputModules->append( aModule );
01283     aModule->setFramework( this );
01284     if ( strlen( aModule->name( ) ) > _maxNameLength ) {
01285       _maxNameLength = strlen( aModule->name( ) );
01286     }
01287   } else {
01288     if (verbose() ) {
01289       partialReport( "Module " );
01290       partialReport( aModule->name( ) );
01291       fullReport   ( " already exists" );
01292     }
01293     delete aModule;
01294   }
01295 }
01296 
01297 void
01298 AppFramework::add( APPPath* const aPath )
01299 {
01300   
01301   assert ( 0 != aPath );
01302   
01303   if ( _executables->add( aPath->name( ), aPath ) ) {
01304     _paths->append( aPath );
01305     aPath->setFramework( this );
01306     if ( strlen( aPath->name( ) ) > _maxNameLength ) {
01307       _maxNameLength = strlen( aPath->name( ) );
01308     }
01309   } else {
01310     partialReport( "Path " );
01311     partialReport( aPath->name( ) );
01312     fullReport   ( " already exists" );
01313     delete aPath;
01314   }
01315 }
01316 
01317 void
01318 AppFramework::add( APPSequence* const aSequence )
01319 {
01320   
01321   assert ( 0 != aSequence );
01322   
01323   if ( _executables->add( aSequence->name( ), aSequence ) ) {
01324     _sequences->append( aSequence );
01325     aSequence->setFramework( this );
01326     if ( strlen( aSequence->name( ) ) > _maxNameLength ) {
01327       _maxNameLength = strlen( aSequence->name( ) );
01328     }
01329   } else {
01330     partialReport( "Sequence " );
01331     partialReport( aSequence->name( ) );
01332     fullReport   ( " already exists" );
01333     delete aSequence;
01334   }
01335 }
01336 void
01337 AppFramework::add( AppCloneRecorder* const aRecorder )
01338 {
01339 
01340   assert ( 0 != aRecorder );
01341   _cloneList->append(aRecorder);
01342 }
01343 void
01344 AppFramework::remove( const APPExecNode* const aNode )
01345 {
01346   
01347   assert ( 0 != aNode );
01348   
01349   _execNodes->remove( (APPExecNode*)aNode );
01350 }
01351 
01352 void
01353 AppFramework::remove( const AppModule* const aModule )
01354 {
01355   
01356   assert ( 0 != aModule );
01357   
01358   _modules->remove( (AppModule*)aModule );
01359   _executables->remove( aModule->name( ) );
01360 }
01361 
01362 void
01363 AppFramework::remove( const AppAccountModule* const aModule )
01364 {
01365 
01366   assert ( 0 != aModule );
01367 
01368   _modules->remove( (AppAccountModule*)aModule );
01369   _executables->remove( aModule->name( ) );
01370 }
01371 
01372 void
01373 AppFramework::remove( const APPInputModule* const aModule )
01374 {
01375   
01376   assert ( 0 != aModule );
01377   
01378   _modules->remove( (APPInputModule*)aModule );
01379   _executables->remove( aModule->name( ) );
01380 }
01381 
01382 void
01383 AppFramework::remove( const APPOutputModule* const aModule )
01384 {
01385   
01386   assert ( 0 != aModule );
01387 
01388     _modules->remove( (APPOutputModule*)aModule );
01389     _executables->remove( aModule->name( ) );
01390 }
01391 
01392 void
01393 AppFramework::remove( const APPPath* const aPath )
01394 {
01395 
01396     assert ( 0 != aPath );
01397 
01398     if (aPath == _defaultPath) _defaultPath = 0;  
01399 
01400     _paths->remove( (APPPath*)aPath );
01401     _executables->remove( aPath->name( ) );
01402 }
01403 
01404 void
01405 AppFramework::remove( const APPSequence* const aSequence )
01406 {
01407 
01408     assert ( 0 != aSequence );
01409 
01410     _sequences->remove( (APPSequence*)aSequence );
01411     _executables->remove( aSequence->name( ) );
01412 
01413     // deleted (nestled) sequences have to be removed 
01414     APPListIterator <APPSequence*> iterSeq(*_sequences);
01415     APPSequence** aSeq;
01416     while (aSeq = iterSeq()) {
01417       (*aSeq)->remove(aSequence);
01418     }
01419     APPListIterator <APPPath*> iterPath(*_paths);
01420     APPPath** aPath;
01421     while (aPath = iterPath()) {
01422       (*aPath)->remove(aSequence);
01423     }
01424 
01425 }
01426 
01427 void
01428 AppFramework::resetAppMethods(bool toThis) {
01429 
01430    AppMethodBase** anAppMethod;
01431 
01432    APPListIterator<AppMethodBase*> itr(*appMethods());  // use the grab bag...
01433    while ( anAppMethod=itr.next() ) {
01434            (*anAppMethod)->reset(false); }              // reset 'em all
01435 }
01436 
01437 void
01438 AppFramework::resetNodes( )
01439 {
01440     APPExecNode** node;
01441 
01442         APPListIterator<APPExecNode*> theIterator( *nodes( ) );
01443         while ( node = theIterator( ) ) {
01444                 (*node)->setExecuted( false );
01445     }
01446 }
01447 #ifdef CDF
01448 void
01449 AppFramework::addCDFrequiredActions( )
01450 {
01451    // Default construct the CDF non-optional actions
01452    AppAction* histAction  = new AppActionHistoDir;
01453    AppAction* timerAction = new AppActionTime;
01454    // Append them to the framework's list
01455    actions( )->append( histAction );
01456    actions( )->append( timerAction );
01457 }
01458 #endif
01459 //
01460 // Return unowned pointer to user builder
01461 //
01462 AppUserBuild*
01463 AppFramework::appBuilder(){
01464   return _theAppUserBuild;
01465 }
01466 
01467 //
01468 // Do any lingering App setup here that the User should
01469 // not be bothered with.
01470 //
01471 
01472 void
01473 AppFramework::setupTheApp(AppUserBuild* build )
01474 {
01475   AbsInterp* absInterp = AbsInterp::theInterpreter(); 
01476   _theAppUserBuild = build; 
01477 
01478   // Create the Actions Controllers
01479   APPListIterator<AppAction*> itr( *actions( ) );
01480   AppAction** anAction;
01481   while ( anAction = itr( ) ) {
01482     actionControllers( )->append( new AppActionController( *anAction ) );
01483   }
01484 
01485   // Build a list with Input, Output and App Modules all stored
01486   // as AppModules (common base class)
01487 
01488   APPList<AppModule*> allAsModules;
01489   buildModuleList( allAsModules, *inputModules() );
01490   buildModuleList( allAsModules, *outputModules() );
01491   buildModuleList( allAsModules, *modules() );
01492   buildModuleList( allAsModules, *accountModules() );
01493 
01494   // Now use that list to check if commands are redefined ...
01495 
01496   APPListIterator<AppModule*> modIter( allAsModules );
01497   AppModule** mod;
01498   disableCommands(); // Framework's
01499   while ( mod = (AppModule**)modIter( ) ) {
01500     APPCommand** aCommand;
01501     APPListIterator<APPCommand*> cmdIter( *((*mod)->commands()) );
01502     while ( aCommand = cmdIter( ) ) {
01503       if ( absInterp->existsCommand((*aCommand)->command()) ) {
01504         partialReport("Error : Redefining command ");
01505         partialReport((*aCommand)->command());
01506         partialReport(" in target ");
01507         fullReport((*mod)->name());
01508         assert(0);
01509       } 
01510       else {
01511         (*aCommand)->enable();
01512       }      
01513     }
01514     cmdIter.rewind();
01515     while ( aCommand = cmdIter( ) ) {
01516       (*aCommand)->disable();
01517     }
01518   }
01519   enableCommands(); // Framework's
01520 }
01521 
01522 // These methods iterate over a source list of specific kinds of modules and append them
01523 // to the destination list as their base class, AppModule.  The Destination should not
01524 // own the modules on it.  No protection from duplication is attempted.
01525 
01526 void
01527 AppFramework::buildModuleList( APPList<AppModule*>& destination ,
01528                                APPList<AppAccountModule*>& source ) {
01529 
01530   APPListIterator<AppAccountModule*> itr( source );
01531   AppModule** m;
01532   while ( m  = (AppModule**) itr( ) ) {
01533     destination.append( *m );
01534   }
01535   return;
01536 }
01537 
01538 void
01539 AppFramework::buildModuleList( APPList<AppModule*>& destination , 
01540                                APPList<APPInputModule*>& source ) {
01541    
01542     APPListIterator<APPInputModule*> itr( source );
01543     AppModule** m;
01544     while ( m  = (AppModule**) itr( ) ) {
01545       destination.append( *m );
01546     }                 
01547     return;
01548 }
01549 
01550 void
01551 AppFramework::buildModuleList( APPList<AppModule*>& destination , 
01552                                APPList<APPOutputModule*>& source ) {
01553    
01554     APPListIterator<APPOutputModule*> itr( source );
01555     AppModule** m;
01556     while ( m  = (AppModule**) itr( ) ) {
01557       destination.append( *m );
01558     }                 
01559     return;
01560 }
01561 
01562 void
01563 AppFramework::buildModuleList( APPList<AppModule*>& destination , 
01564                                APPList<AppModule*>& source ) {
01565    
01566     destination.append( source );
01567 
01568     return;
01569 }
01570 
01571 //
01572 // CXX template instantiations
01573 //
01574 #if defined(__DECCXX) || defined(CDF)
01575 template class APPHash< APPExecutable >;
01576 #endif // __DECCXX
01577 
01578 // This function is for use only by Framework.
01579 // Here, Item is always a pointer and has a name() method.
01580 template <class Item>
01581 void APPListDeleteAll( APPList<Item> & alist, AppFramework* theFrame, 
01582                        const char* itemType) {
01583 #ifdef CDF
01584   APPListDeleteAll(alist);
01585 #else
01586   // order of deletion is important, especially for modules which 
01587   // have dtors calling other modules.  (order is first in, last deleted.)
01588   Item *p_item;  
01589   while ( p_item = alist.last() ) {
01590     Item temp_item = *p_item; 
01591     FwkString identity = (*p_item)->name();       
01592     alist.remove(p_item) ;        
01593     if (theFrame->verbose()) {
01594       theFrame->partialReport( ComTimeStamp() );
01595       theFrame->partialReport( " Before dtor of " );
01596       theFrame->partialReport( itemType );
01597       theFrame->partialReport( " " );
01598       theFrame->fullReport( identity );
01599     }
01600     delete temp_item ;            
01601     if (theFrame->verbose()) {
01602       theFrame->partialReport( ComTimeStamp() );
01603       theFrame->partialReport( " After  dtor of " );
01604       theFrame->partialReport( itemType );
01605       theFrame->partialReport( " " );
01606       theFrame->fullReport(identity);
01607     }
01608   }
01609 #endif
01610 }
01611 

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002