TTask.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TTask.cxx 31827 2009-12-11 07:52:09Z brun $
00002 // Author: Rene Brun   02/09/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //______________________________________________________________________________
00013 //
00014 // TTask is a base class that can be used to build a complex tree of Tasks.
00015 // Each TTask derived class may contain other TTasks that can be executed
00016 // recursively, such that a complex program can be dynamically built and executed
00017 // by invoking the services of the top level Task or one of its subtasks.
00018 //
00019 // Use the TTask::Add function to add a subtask to an existing TTask.
00020 // To execute a TTask, one calls the ExecuteTask function. ExecuteTask will
00021 // call recursively:
00022 //     - the TTask::Exec function of the derived class
00023 //     - TTask::ExecuteTasks to execute for each task the list of its subtasks.
00024 // If the top level task (see example below) is added to the list of Root
00025 // browsable objects, the tree of tasks can be visualized by the Root browser.
00026 // The browser can be used to start a task, set break points at the beginning
00027 // of a task or when the task has completed. At a breakpoint, data structures
00028 // generated by the execution up this point may be inspected asyncronously
00029 // and then the execution can be resumed by selecting the "Continue" function
00030 // of a task.
00031 //
00032 // A Task may be active or inactive (controlled by TTask::SetActive).
00033 // When a task is not active, its sub tasks are not executed.
00034 //
00035 // A TTask tree may be made persistent, saving the status of all the tasks.
00036 //
00037 // The picture in the Root browser below has been generated by executing
00038 // the following script:
00039 //
00040 //{ //------------------script tasks.C---------------------------
00041 //   TTask *aliroot  = new TTask("aliroot","ALICE reconstruction main task");
00042 //   TTask *geominit = new TTask("geomInit","Initialize ALICE geometry");
00043 //   TTask *matinit  = new TTask("matInit","Initialize ALICE materials");
00044 //   TTask *physinit = new TTask("physInit","Initialize Physics processes");
00045 //   TTask *tracker  = new TTask("tracker","Track reconstruction manager");
00046 //   TTask *tpcrec   = new TTask("tpcrec","TPC reconstruction");
00047 //   TTask *itsrec   = new TTask("itsrec","ITS reconstruction");
00048 //   TTask *muonrec  = new TTask("muonRec","Muon Reconstruction");
00049 //   TTask *phosrec  = new TTask("phosRec","Phos Reconstruction");
00050 //   TTask *richrec  = new TTask("richRec","Rich Reconstruction");
00051 //   TTask *trdrec   = new TTask("trdRec","TRD Reconstruction");
00052 //   TTask *globrec  = new TTask("globRec","Global Track Reconstruction");
00053 //   TTask *pstats   = new TTask("printStats","Print Run Statistics");
00054 //   TTask *run      = new TTask("run","Process one run");
00055 //   TTask *event    = new TTask("event","Process one event");
00056 //   aliroot->Add(geominit);
00057 //   aliroot->Add(matinit);
00058 //   aliroot->Add(physinit);
00059 //   aliroot->Add(run);
00060 //   run->Add(event);
00061 //   event->Add(tracker);
00062 //   event->Add(muonrec);
00063 //   event->Add(phosrec);
00064 //   event->Add(richrec);
00065 //   event->Add(trdrec);
00066 //   event->Add(globrec);
00067 //   tracker->Add(tpcrec);
00068 //   tracker->Add(itsrec);
00069 //   run->Add(pstats);
00070 //
00071 //   gROOT->GetListOfBrowsables()->Add(aliroot,"aliroot");
00072 //   new TBrowser;
00073 //} //-------------------------------------------------------------
00074 //
00075 //Begin_Html
00076 /*
00077 <img src="gif/tasks.gif">
00078 */
00079 //End_Html
00080 
00081 #include "Riostream.h"
00082 #include "TTask.h"
00083 #include "TBrowser.h"
00084 #include "TROOT.h"
00085 #include "TRegexp.h"
00086 
00087 TTask *TTask::fgBeginTask  = 0;
00088 TTask *TTask::fgBreakPoint = 0;
00089 
00090 ClassImp(TTask)
00091 
00092 //______________________________________________________________________________
00093 TTask::TTask()
00094 {
00095    // Default constructor invoked when reading a TTask object from a file.
00096 
00097    fHasExecuted = kFALSE;
00098    fActive      = kTRUE;
00099    fBreakin     = 0;
00100    fBreakout    = 0;
00101    fTasks       = 0;
00102 }
00103 
00104 //______________________________________________________________________________
00105 TTask::TTask(const char* name, const char *title)
00106       : TNamed(name,title)
00107 {
00108    // Standard constructor.
00109 
00110    fHasExecuted = kFALSE;
00111    fActive      = kTRUE;
00112    fBreakin     = 0;
00113    fBreakout    = 0;
00114    fTasks       = new TList();
00115 }
00116 //______________________________________________________________________________
00117 
00118 TTask& TTask::operator=(const TTask& tt)         
00119 {        
00120    //assignment operator (PLEASE DO NOT USE THIS IS WRONG)       
00121    if(this!=&tt) {       
00122       TNamed::operator=(tt);     
00123       fTasks->Delete();
00124       TIter next(tt.fTasks);
00125       TTask *task;
00126       while ((task = (TTask*)next())) {
00127          fTasks->Add(new TTask(*task));
00128       }      
00129       fOption=tt.fOption;        
00130       fBreakin=tt.fBreakin;      
00131       fBreakout=tt.fBreakout;    
00132       fHasExecuted=tt.fHasExecuted;      
00133       fActive=tt.fActive;        
00134    }     
00135    return *this;         
00136 }        
00137 
00138 //______________________________________________________________________________         //______________________________________________________________________________
00139 TTask::TTask(const TTask &other) : TNamed(other)         
00140 {        
00141    // Copy constructor. 
00142    fTasks = new TList();         
00143    TIter next(other.fTasks);
00144    TTask *task;
00145    while ((task = (TTask*)next())) {
00146       fTasks->Add(new TTask(*task));
00147    }
00148    fOption = other.fOption;
00149    fBreakin = other.fBreakin;
00150    fBreakout = other.fBreakout;
00151    fHasExecuted = kFALSE;
00152    fActive = other.fActive;   
00153 }        
00154 
00155 //______________________________________________________________________________
00156 TTask::~TTask()
00157 {
00158    // Delete a task and its subtasks.
00159    if (!fTasks) return;
00160    fTasks->Delete();
00161    delete fTasks;
00162 }
00163 
00164 //______________________________________________________________________________
00165 void TTask::Abort()
00166 {
00167    // Abort current tree of tasks.
00168    // After this call, the tree of tasks is ready to be executed again.
00169    // The application must take care of cleaning data structures created
00170    // by previous executions.
00171 
00172    if (!fgBeginTask) {
00173       printf(" Nothing to abort: No task currently running\n");
00174       return;
00175    }
00176    CleanTasks();
00177    fgBeginTask  = 0;
00178    fgBreakPoint = 0;
00179 }
00180 
00181 //______________________________________________________________________________
00182 void TTask::Browse(TBrowser *b)
00183 {
00184    // Browse the list of tasks.
00185    // It is recommended to add the top level task to the list of
00186    // ROOT browsables by:
00187    //    gROOT->GetListOfBrowsables()->Add(myTopLevelTask)
00188 
00189    fTasks->Browse(b);
00190 }
00191 
00192 //______________________________________________________________________________
00193 void TTask::CleanTasks()
00194 {
00195    // Reset tasks state: breakpoints and execute flags
00196    // also invokes the Clear function of each task to clear all data
00197    // structures created by a previous execution of a task.
00198 
00199    if (fBreakin)  fBreakin  = 1;
00200    if (fBreakout) fBreakout = 1;
00201    fHasExecuted = kFALSE;
00202    Clear();
00203    TIter next(fTasks);
00204    TTask *task;
00205    while((task=(TTask*)next())) {
00206       task->CleanTasks();
00207    }
00208 }
00209 
00210 //______________________________________________________________________________
00211 void TTask::Clear(Option_t *)
00212 {
00213    // Recursively call the Clear function of this task and its subtasks.
00214    // The Clear function must be implemented for each derived class
00215    // to clear all data structures created by a previous execution of a task.
00216    // This function is automatically called by the CleanTasks function.
00217 }
00218 
00219 //______________________________________________________________________________
00220 void TTask::Continue()
00221 {
00222    // Resume execution at the current break point.
00223 
00224    if (!fgBeginTask) {
00225       printf(" No task to continue\n");
00226       return;
00227    }
00228    fgBreakPoint = 0;
00229 
00230    fgBeginTask->ExecuteTasks(fOption.Data());
00231 
00232    if (!fgBreakPoint) {
00233       fgBeginTask->CleanTasks();
00234       fgBeginTask = 0;
00235    }
00236 }
00237 
00238 //______________________________________________________________________________
00239 void TTask::Exec(Option_t *)
00240 {
00241    // Dummy Execute.
00242    // This function must be redefined in the derived classes.
00243 }
00244 
00245 //______________________________________________________________________________
00246 void TTask::ExecuteTask(Option_t *option)
00247 {
00248    // Execute main task and its subtasks.
00249    // When calling this function, the Exec function of the corresponding class
00250    // is invoked, then the list of its subtasks is executed calling recursively
00251    // all the subtasks, etc.
00252    //
00253    // The option parameter may be used to select different execution steps
00254    // within a task. This parameter is passed also to all the subtasks.
00255 
00256    if (fgBeginTask) {
00257       Error("ExecuteTask","Cannot execute task:%s, already running task: %s",GetName(),fgBeginTask->GetName());
00258       return;
00259    }
00260    if (!IsActive()) return;
00261 
00262    fOption = option;
00263    fgBeginTask = this;
00264    fgBreakPoint = 0;
00265 
00266    if (fBreakin) return;
00267    if (gDebug > 1) {
00268       TROOT::IndentLevel();
00269       cout<<"Execute task:"<<GetName()<<" : "<<GetTitle()<<endl;
00270       TROOT::IncreaseDirLevel();
00271    }
00272    Exec(option);
00273 
00274    fHasExecuted = kTRUE;
00275    ExecuteTasks(option);
00276 
00277    if (gDebug > 1) TROOT::DecreaseDirLevel();
00278    if (fBreakout) return;
00279 
00280    if (!fgBreakPoint) {
00281       fgBeginTask->CleanTasks();
00282       fgBeginTask = 0;
00283    }
00284 }
00285 
00286 //______________________________________________________________________________
00287 void TTask::ExecuteTasks(Option_t *option)
00288 {
00289    // Execute all the subtasks of a task.
00290 
00291    TIter next(fTasks);
00292    TTask *task;
00293    while((task=(TTask*)next())) {
00294       if (fgBreakPoint) return;
00295       if (!task->IsActive()) continue;
00296       if (task->fHasExecuted) {
00297          task->ExecuteTasks(option);
00298          continue;
00299       }
00300       if (task->fBreakin == 1) {
00301          printf("Break at entry of task: %s\n",task->GetName());
00302          fgBreakPoint = this;
00303          task->fBreakin++;
00304          return;
00305       }
00306 
00307       if (gDebug > 1) {
00308          TROOT::IndentLevel();
00309          cout<<"Execute task:"<<task->GetName()<<" : "<<task->GetTitle()<<endl;
00310          TROOT::IncreaseDirLevel();
00311       }
00312       task->Exec(option);
00313       task->fHasExecuted = kTRUE;
00314       task->ExecuteTasks(option);
00315       if (gDebug > 1) TROOT::DecreaseDirLevel();
00316       if (task->fBreakout == 1) {
00317          printf("Break at exit of task: %s\n",task->GetName());
00318          fgBreakPoint = this;
00319          task->fBreakout++;
00320          return;
00321       }
00322    }
00323 }
00324 
00325 //______________________________________________________________________________
00326 void TTask::ls(Option_t *option) const
00327 {
00328    // List the tree of tasks.
00329    // Indentation is used to identify the task tree.
00330 
00331    TROOT::IndentLevel();
00332    cout <<GetName()<<"\t"<<GetTitle()<<endl;
00333    TROOT::IncreaseDirLevel();
00334 
00335    TString opta = option;
00336    TString opt  = opta.Strip(TString::kBoth);
00337 
00338    TRegexp re(opt, kTRUE);
00339 
00340    TObject *obj;
00341    TIter nextobj(fTasks);
00342    while ((obj = (TObject *) nextobj())) {
00343       TString s = obj->GetName();
00344       if (s.Index(re) == kNPOS) continue;
00345       obj->ls(option);
00346    }
00347    TROOT::DecreaseDirLevel();
00348 }

Generated on Tue Jul 5 14:11:24 2011 for ROOT_528-00b_version by  doxygen 1.5.1