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

Last change on this file since 959 was 959, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 10.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#include "MFilter.h"
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->PreProcess(fParList))
235 return kFALSE;
236
237 task->SetIsPreprocessed();
238 }
239
240 *fLog << endl;
241
242 return kTRUE;
243}
244
245// --------------------------------------------------------------------------
246//
247// do the event execution of all tasks in the task-list
248//
249Bool_t MTaskList::Process()
250{
251 //
252 // Reset the ReadyToSave flag.
253 // Reset all containers.
254 //
255 // FIXME: To run a tasklist as a single task in another tasklist we
256 // have to make sure, that the Parameter list isn't reset.
257 //
258 fParList->SetReadyToSave(kFALSE);
259 fParList->Reset();
260
261 //
262 // create the Iterator for the TaskList
263 //
264 TIter Next(&fTasks);
265 MTask *task=NULL;
266
267 //
268 // loop over all tasks for processing
269 //
270 while ( (task=(MTask*)Next()) )
271 {
272 //
273 // if the task has the wrong stream id skip it.
274 //
275 if (strcmp(GetStreamId(), task->GetStreamId()) &&
276 strcmp(task->GetStreamId(), "All"))
277 continue;
278
279 //
280 // Check for the existance of a filter. If a filter is existing
281 // check for its value. If the value is kFALSE don't execute
282 // this task.
283 //
284 const MFilter *filter = task->GetFilter();
285
286 const Bool_t rc = filter ? filter->IsExpressionTrue() : kTRUE;
287
288 if (!rc)
289 continue;
290
291 //
292 // if it has the right stream id execute the Process() function
293 // and check what the result of it is.
294 //
295 switch (task->Process())
296 {
297 case kTRUE:
298 //
299 // everything was OK: go on
300 //
301 continue;
302
303 case kFALSE:
304 //
305 // an error occured: stop eventloop
306 //
307 return kFALSE;
308
309 case kCONTINUE:
310 //
311 // something occured: skip the rest of the tasks for this event
312 //
313 return kTRUE;
314 }
315 }
316 return kTRUE;
317}
318
319// --------------------------------------------------------------------------
320//
321// do post processing (before eventloop) of all tasks in the task-list
322//
323Bool_t MTaskList::PostProcess()
324{
325 *fLog << "Postprocessing... " << flush;
326
327 // FIXME: At the moment all tasks are post processed independ of
328 // whether it was preprocessed or not.
329
330 //
331 // Reset the ReadyToSave flag.
332 // Reset all containers.
333 //
334 // FIXME: To run a tasklist as a single task in another tasklist we
335 // have to make sure, that the Parameter list isn't reset.
336 //
337 fParList->SetReadyToSave(kFALSE);
338 fParList->Reset();
339
340 //
341 // create the Iterator for the TaskList
342 //
343 TIter Next(&fTasks);
344
345 MTask *task=NULL;
346
347 //
348 // loop over all tasks for postprocessing
349 //
350 while ( (task=(MTask*)Next()) )
351 {
352 if (!task->IsPreprocessed())
353 continue;
354
355 *fLog << task->GetName() << "... " << flush;
356
357 if (!task->PostProcess())
358 return kFALSE;
359 }
360
361 *fLog << endl;
362
363 return kTRUE;
364}
365
366// --------------------------------------------------------------------------
367void MTaskList::Print(Option_t *t)
368{
369 *fLog << "TaskList: " << this->GetName() << " <" << this->GetTitle() << ">" << endl;
370
371 fTasks.Print();
372
373 *fLog << endl;
374}
375
Note: See TracBrowser for help on using the repository browser.