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

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