source: trunk/MagicSoft/Mars/mbase/MTaskList.cc@ 1006

Last change on this file since 1006 was 1006, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 11.5 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 12/2000 (tbretz@uni-sw.gwdg.de)
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MTaskList //
28// //
29// Collection of tasks. //
30// //
31// A tasklist is necessary to run the eventloop. It contains the scheduled //
32// tasks, which should be executed in your program. //
33// //
34// To add a task use AddToList. //
35// //
36// The tasklist itself is a task, too. You can add a tasklist to another //
37// tasklist. This makes sense, if you want to filter the execution of //
38// more than one task of your tasklist using the same filter. //
39// //
40// The tasks in the list are idetified by their names. If more than one //
41// task has the same name, the tasklist will still work correctly, but //
42// you might run into trouble trying to get a pointer to a task by name //
43// from the list. //
44// //
45/////////////////////////////////////////////////////////////////////////////
46
47#include "MTaskList.h"
48
49#include <TOrdCollection.h>
50
51#include "MLog.h"
52#include "MLogManip.h"
53
54#include "MParList.h"
55#include "MInputStreamID.h"
56
57ClassImp(MTaskList);
58
59// --------------------------------------------------------------------------
60//
61// the name for the task list must be the same for all task lists
62// because the task list (at the moment) is identified by exactly
63// this name in the parameter list (by MEvtLoop::SetParList)
64//
65MTaskList::MTaskList(const char *name, const char *title)
66{
67 fName = name ? name : "MTaskList";
68 fTitle = title ? title : "A list for tasks to be executed";
69
70 fTasks = new TOrdCollection;
71}
72
73// --------------------------------------------------------------------------
74//
75// CopyConstructor
76// creates a new TaskList and put the contents of an existing
77// TaskList in the new TaskList.
78//
79MTaskList::MTaskList(MTaskList &ts)
80{
81 fTasks->AddAll(ts.fTasks);
82}
83
84// --------------------------------------------------------------------------
85//
86// If the 'IsOwner' bit is set (via SetOwner()) all tasks are deleted
87// by the destructor
88//
89MTaskList::~MTaskList()
90{
91 if (TestBit(kIsOwner))
92 fTasks->SetOwner();
93
94 delete fTasks;
95}
96
97// --------------------------------------------------------------------------
98//
99// If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted
100// by the destructor
101//
102inline void MTaskList::SetOwner(Bool_t enable)
103{
104 enable ? SetBit(kIsOwner) : ResetBit(kIsOwner);
105}
106
107
108// --------------------------------------------------------------------------
109//
110// Set the logging stream for the all tasks in the list and the tasklist
111// itself.
112//
113void MTaskList::SetLogStream(MLog *log)
114{
115 //
116 // create the Iterator over the tasklist
117 //
118 TIter Next(fTasks);
119
120 MTask *task=NULL;
121
122 //
123 // loop over all tasks for preproccesing
124 //
125 while ((task=(MTask*)Next()))
126 task->SetLogStream(log);
127
128 MParContainer::SetLogStream(log);
129}
130
131
132// --------------------------------------------------------------------------
133//
134// schedule task for execution, whether as first task, or after
135// 'where'. 'tType' is the event type which should be processed
136//
137Bool_t MTaskList::AddToList(MTask *task, const char *type, MTask *where)
138{
139 // FIXME: We agreed to put the task into list in an ordered way.
140
141 //
142 // Sanity check
143 //
144 if (!task)
145 return kFALSE;
146
147 //
148 // Get Name of new task
149 //
150 const char *name = task->GetName();
151
152 //
153 // Check if the new task is already existing in the list
154 //
155 const TObject *objn = fTasks->FindObject(name);
156 const TObject *objt = fTasks->FindObject(task);
157
158 if (objn || objt)
159 {
160 //
161 // If the task is already in the list ignore it.
162 //
163 if (objt || objn==task)
164 {
165 *fLog << dbginf << "Warning: Task '" << task->GetName() << ", 0x" << (void*)task;
166 *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl;
167 return kTRUE;
168 }
169
170 //
171 // Otherwise add it to the list, but print a warning message
172 //
173 *fLog << dbginf << "Warning: Task '" << task->GetName();
174 *fLog << "' already existing in '" << GetName() << "'." << endl;
175 *fLog << "You may not be able to get a pointer to this task by name." << endl;
176 }
177
178 if (where)
179 {
180 if (!fTasks->FindObject(where))
181 {
182 *fLog << dbginf << "Error: Cannot find task after which the new task should be scheduled!" << endl;
183 return kFALSE;
184 }
185 }
186
187 *fLog << "Adding " << name << " to " << GetName() << " for " << type << "... " << flush;
188
189 task->SetStreamId(type);
190 fTasks->Add(task);
191
192 *fLog << "Done." << endl;
193
194 return kTRUE;
195}
196
197// --------------------------------------------------------------------------
198//
199// Find an object in the list.
200// 'name' is the name of the object you are searching for.
201//
202TObject *MTaskList::FindObject(const char *name) const
203{
204 return fTasks->FindObject(name);
205}
206
207// --------------------------------------------------------------------------
208//
209// check if the object is in the list or not
210//
211TObject *MTaskList::FindObject(TObject *obj) const
212{
213 return fTasks->FindObject(obj);
214}
215
216// --------------------------------------------------------------------------
217//
218// do pre processing (before eventloop) of all tasks in the task-list
219//
220Bool_t MTaskList::PreProcess(MParList *pList)
221{
222 *fLog << "Preprocessing... " << flush;
223
224 fParList = pList;
225
226 //
227 // create the Iterator over the tasklist
228 //
229 TIter Next(fTasks);
230
231 MTask *task=NULL;
232
233 //
234 // loop over all tasks for preproccesing
235 //
236 while ((task=(MTask*)Next()))
237 {
238 *fLog << task->GetName() << "... " << flush;
239
240 if (!task->CallPreProcess(fParList))
241 return kFALSE;
242 }
243
244 *fLog << endl;
245
246 return kTRUE;
247}
248
249// --------------------------------------------------------------------------
250//
251// do the event execution of all tasks in the task-list
252//
253Bool_t MTaskList::Process()
254{
255 //
256 // Reset the ReadyToSave flag.
257 // Reset all containers.
258 //
259 // FIXME: To run a tasklist as a single task in another tasklist we
260 // have to make sure, that the Parameter list isn't reset.
261 //
262 fParList->SetReadyToSave(kFALSE);
263 fParList->Reset();
264
265 //
266 // create the Iterator for the TaskList
267 //
268 TIter Next(fTasks);
269 MTask *task=NULL;
270
271 //
272 // loop over all tasks for processing
273 //
274 while ( (task=(MTask*)Next()) )
275 {
276 //
277 // if the task has the wrong stream id skip it.
278 //
279 if (GetStreamId() != task->GetStreamId() &&
280 task->GetStreamId() != "All")
281 continue;
282
283 //
284 // if it has the right stream id execute the CallProcess() function
285 // and check what the result of it is.
286 // The CallProcess() function increases the execution counter and
287 // calls the Process() function dependent on the existance and
288 // return value of a filter.
289 //
290 switch (task->CallProcess())
291 {
292 case kTRUE:
293 //
294 // everything was OK: go on with the next task
295 //
296 continue;
297
298 case kFALSE:
299 //
300 // an error occured: stop eventloop
301 //
302 return kFALSE;
303
304 case kCONTINUE:
305 //
306 // something occured: skip the rest of the tasks for this event
307 //
308 return kTRUE;
309
310 default:
311 *fLog << "MTaskList::Process: Unknown return value from MTask::Process()... ignored." << endl;
312 }
313 }
314 return kTRUE;
315}
316
317// --------------------------------------------------------------------------
318//
319// do post processing (before eventloop) of all tasks in the task-list
320// only tasks which have successfully been preprocessed are postprocessed.
321//
322Bool_t MTaskList::PostProcess()
323{
324 *fLog << "Postprocessing... " << flush;
325
326 //
327 // Reset the ReadyToSave flag.
328 // Reset all containers.
329 //
330 // FIXME: To run a tasklist as a single task in another tasklist we
331 // have to make sure, that the Parameter list isn't reset.
332 //
333 fParList->SetReadyToSave(kFALSE);
334 fParList->Reset();
335
336 //
337 // create the Iterator for the TaskList
338 //
339 TIter Next(fTasks);
340
341 MTask *task=NULL;
342
343 //
344 // loop over all tasks for postprocessing
345 // only tasks which have successfully been preprocessed are postprocessed.
346 //
347 while ( (task=(MTask*)Next()) )
348 {
349 if (!task->CallPostProcess())
350 return kFALSE;
351
352 *fLog << task->GetName() << "... " << flush;
353 }
354
355 *fLog << endl;
356
357 return kTRUE;
358}
359
360// --------------------------------------------------------------------------
361//
362// Prints the number of times all the tasks in the list has been.
363// For convinience the lvl argument results in a number of spaces at the
364// beginning of the line. So that the structur of a tasklist can be
365// identified. Use MTaskList::PrintStatistics without an argument.
366//
367void MTaskList::PrintStatistics(const Int_t lvl) const
368{
369 if (lvl==0)
370 {
371 *fLog << endl;
372 *fLog << "Execution Statistics: " << endl;
373 *fLog << "---------------------" << endl;
374 *fLog << GetName() << " [" << ClassName() << "]" << endl;
375 }
376 else
377 {
378 *fLog << setw(lvl) << " " << GetName() << " [";
379 *fLog << ClassName() << "]" << endl;
380 }
381
382 //
383 // create the Iterator for the TaskList
384 //
385 TIter Next(fTasks);
386
387 MTask *task=NULL;
388 //
389 // loop over all tasks for postprocessing
390 // only tasks which have successfully been preprocessed are postprocessed.
391 //
392 while ( (task=(MTask*)Next()) )
393 task->PrintStatistics(lvl+1);
394
395 if (lvl==0)
396 *fLog << endl;
397}
398
399// --------------------------------------------------------------------------
400void MTaskList::Print(Option_t *t) const
401{
402 *fLog << "TaskList: " << GetName() << " <" << GetTitle() << ">" << endl;
403
404 fTasks->Print();
405
406 *fLog << endl;
407}
408
Note: See TracBrowser for help on using the repository browser.