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

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