source: trunk/Mars/mbase/MParList.cc@ 20051

Last change on this file since 20051 was 19345, checked in by tbretz, 6 years ago
Improves the behaviour with RecursiveRemove. Strictly speaking this change might only be necessary if a class contains more than one member which is bound to recursive remove. Onth other hand setting all members to NULL which might be affected by RecursiveRemove is not wrong either.
File size: 29.2 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 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MParList //
28// //
29// This class contains a list of different parameter containers. //
30// //
31// A parameter container is an object which is derived from //
32// MParContainer. //
33// //
34// Normally a parameter container is used for data exchange between two //
35// tasks at runtime. //
36// //
37// You can add every parameter container (Named object) to the //
38// instance and access it from somewhere else via its Name. //
39// //
40/////////////////////////////////////////////////////////////////////////////
41#include "MParList.h"
42
43#include <fstream> // ofstream, SavePrimitive
44
45#include <TNamed.h>
46#include <TClass.h>
47#include <TOrdCollection.h>
48
49#include "MLog.h"
50#include "MLogManip.h"
51
52#include "MIter.h"
53#include "MParEnv.h"
54#include "MTaskList.h"
55
56ClassImp(MParList);
57
58using namespace std;
59
60static const TString gsDefName = "MParList";
61static const TString gsDefTitle = "A list of Parameter Containers";
62
63// --------------------------------------------------------------------------
64//
65// creates an empty list
66//
67void MParList::Init(const char *name, const char *title)
68{
69 fName = name ? name : gsDefName.Data();
70 fTitle = title ? title : gsDefTitle.Data();
71
72 //
73 // This sets a flag that the list is the owner, which means
74 // that the destructor of the list deletes all it's objects
75 //
76 fContainer = new TOrdCollection;
77 fAutodelete = new TOrdCollection;
78
79 gROOT->GetListOfCleanups()->Add(fContainer);
80 gROOT->GetListOfCleanups()->Add(fAutodelete);
81 fContainer->SetBit(kMustCleanup);
82 fAutodelete->SetBit(kMustCleanup);
83}
84
85
86// --------------------------------------------------------------------------
87//
88// default constructor
89// creates an empty list
90//
91MParList::MParList(const char *name, const char *title)
92{
93 Init(name, title);
94}
95
96// --------------------------------------------------------------------------
97//
98// Copy constructor. It copies all entries of the parameter list, but it
99// takes care of, that the automatically created entries are only deleted
100// once. (doesn't copy the list which holds the automatically created
101// entries)
102//
103MParList::MParList(const MParList &ts, const char *name, const char *title) : MParContainer()
104{
105 Init(name, title);
106
107 fContainer->AddAll(ts.fContainer);
108}
109
110// --------------------------------------------------------------------------
111//
112// If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted
113// by the destructor
114//
115MParList::~MParList()
116{
117 //
118 // Case:
119 // 1) MParList is owner of the containers:
120 // All container are stored in fContainer, and become deleted by
121 // 'delete fContainer'. Some of these containers, which were
122 // created automatically are stored in fAutodelete, too. To prevent
123 // double deletion this containers are not deleted by the destructor
124 // of fAutodelete.
125 // 2) MParList is not owner of the containers:
126 // The containers which were Added by AddToList are not touched.
127 // Only the containers which were created automatically are also
128 // automatically deleted.
129 //
130 IsOwner() ? fContainer->SetOwner() : fAutodelete->SetOwner();
131
132 TIter Next(fContainer);
133 TObject *o=0;
134 while ((o=Next()))
135 if (o->TestBit(kCanDelete))
136 delete fContainer->Remove(o);
137
138 // FIXME? If fContainer is owner do we have to remove the object
139 // from fAutodelete due to the access when checking for a
140 // garbage collection?
141 delete fContainer;
142 fContainer = 0;
143
144 delete fAutodelete;
145 fAutodelete = 0;
146
147}
148
149// --------------------------------------------------------------------------
150//
151// If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted
152// by the destructor
153//
154void MParList::SetOwner(Bool_t enable)
155{
156 enable ? SetBit(kIsOwner) : ResetBit(kIsOwner);
157}
158
159// --------------------------------------------------------------------------
160//
161// Set the logging streamer of the parameter list and all contained
162// parameter containers
163//
164void MParList::SetLogStream(MLog *log)
165{
166 fContainer->R__FOR_EACH(MParContainer, SetLogStream)(log);
167 MParContainer::SetLogStream(log);
168}
169
170void MParList::SetDisplay(MStatusDisplay *d)
171{
172 fContainer->R__FOR_EACH(MParContainer, SetDisplay)(d);
173 MParContainer::SetDisplay(d);
174}
175
176// --------------------------------------------------------------------------
177//
178// Add a single container to the list.
179//
180// If 'where' is given, the object will be added after this.
181//
182Bool_t MParList::AddToList(MParContainer *cont, MParContainer *where)
183{
184 //
185 // check if the object (you want to add) exists
186 //
187 if (!cont)
188 return kFALSE;
189
190 if (cont==this)
191 {
192 *fLog << err << dbginf << "Error: It is not allowed to add a parameter list to itself." << endl;
193 return kFALSE;
194 }
195
196 //
197 // Get Name of new container
198 //
199 const char *name = cont->GetName();
200
201 //
202 // Check if the new container is already existing in the list
203 //
204 const TObject *objn = fContainer->FindObject(name);
205 const TObject *objt = fContainer->FindObject(cont);
206
207 if (objn || objt)
208 {
209 //
210 // If the container is already in the list ignore it.
211 //
212 if (objt || objn==cont)
213 {
214 *fLog << warn << dbginf << "Warning: Container '" << cont->GetName() << ", 0x" << (void*)cont;
215 *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl;
216 return kTRUE;
217 }
218
219 //
220 // Otherwise add it to the list, but print a warning message
221 //
222 *fLog << warn << dbginf << "Warning: Container with the same name '" << cont->GetName();
223 *fLog << "' already existing in '" << GetName() << "'." << endl;
224 *fLog << "You may not be able to get a pointer to container task by name." << endl;
225 }
226
227 //
228 // check if you want to add the new parameter container somewhere
229 // special (in that case you specify "where")
230 //
231 if (where)
232 {
233 if (!fContainer->FindObject(where))
234 {
235 *fLog << err << dbginf << "Error: Cannot find parameter container after which the new one should be added!" << endl;
236 return kFALSE;
237 }
238 }
239
240 if (!cont->InheritsFrom(MParContainer::Class()))
241 {
242 *fLog << err << dbginf << "Error: Cantainer MUST derive from MParContainer!" << endl;
243 return kFALSE;
244 }
245
246 *fLog << inf3 << "Adding " << name << " to " << GetName() << "... " << flush;
247
248 cont->SetBit(kMustCleanup);
249 fContainer->Add(cont);
250 *fLog << "done." << endl;
251
252 return kTRUE;
253}
254
255// --------------------------------------------------------------------------
256//
257// Add all entries which derive from MParContainer
258// of the TObjArray to the list.
259//
260void MParList::AddToList(TObjArray *list)
261{
262 //
263 // check if the object (you want to add) exists
264 //
265 if (!list)
266 return;
267
268 TIter Next(list);
269
270 TObject *cont = NULL;
271 while ((cont=Next()))
272 {
273 MParContainer *par = dynamic_cast<MParContainer*>(cont);
274 if (par)
275 AddToList(par);
276 }
277}
278
279// --------------------------------------------------------------------------
280//
281// Find an object with the same name in the list and replace it with
282// the new one. If the kIsOwner flag is set and the object was not
283// created automatically, the object is deleted.
284//
285Bool_t MParList::Replace(MParContainer *cont)
286{
287 //
288 // check if the object (you want to add) exists
289 //
290 if (!cont)
291 return kFALSE;
292
293 TObject *obj = FindObject(cont->GetName());
294 if (!obj)
295 {
296 *fLog << warn << "No object with the same name '";
297 *fLog << cont->GetName() << "' in list... adding." << endl;
298 return AddToList(cont);
299 }
300
301 fContainer->Remove(obj);
302
303 if (IsOwner() && !fAutodelete->FindObject(obj))
304 delete obj;
305
306 *fLog << inf2 << "MParContainer '" << cont->GetName() << "' found and replaced..." << endl;
307
308 return AddToList(cont);
309}
310
311// --------------------------------------------------------------------------
312//
313// Find an object with the same name in the list and remove it.
314// If the kIsOwner flag is set and the object was not created
315// automatically, the object is deleted.
316//
317void MParList::Remove(MParContainer *cont)
318{
319 //
320 // check if the object (you want to add) exists
321 //
322 if (!cont)
323 return;
324
325 TObject *obj = fContainer->Remove(cont);
326
327 fContainer->RecursiveRemove(obj);
328
329 // if (!obj)
330 // {
331 // *fLog << warn << "Object not found in list..." << endl;
332 // return;
333 //}
334
335// *fLog << inf << "MParContainer '" << cont->GetName() << "' removed..." << endl;
336
337 if (obj && IsOwner() && !fAutodelete->FindObject(obj))
338 delete obj;
339}
340
341// --------------------------------------------------------------------------
342//
343// Call MParContainer::RecursiveRemove
344// Call fContainer->RecursiveRemove
345//
346void MParList::RecursiveRemove(TObject *obj)
347{
348 MParContainer::RecursiveRemove(obj);
349
350 if (obj==fContainer)
351 fContainer = NULL;
352
353 if (fContainer)
354 fContainer->RecursiveRemove(obj);
355}
356
357// --------------------------------------------------------------------------
358//
359// Find an object in the list.
360// 'name' is the name of the object you are searching for.
361//
362TObject *MParList::FindObject(const char *name) const
363{
364 TObject *obj = fContainer->FindObject(name);
365 const MParEnv *env = dynamic_cast<const MParEnv*>(obj);
366 return env ? env->GetCont() : obj;
367}
368
369// --------------------------------------------------------------------------
370//
371// check if the object is in the list or not
372//
373TObject *MParList::FindObject(const TObject *obj) const
374{
375 TObject *ret = fContainer->FindObject(obj);
376 const MParEnv *env = dynamic_cast<const MParEnv*>(ret);
377 return env ? env->GetCont() : ret;
378}
379
380// --------------------------------------------------------------------------
381//
382// Find an object in the list and check for the correct inheritance.
383// 'name' is the name of the object you are searching for.
384//
385// In words: Find object name and check whether it inherits from classname
386//
387TObject *MParList::FindObject(const char *name, const char *classname) const
388{
389 TObject *obj = FindObject(name);
390
391 if (!obj)
392 return NULL;
393
394 if (obj->InheritsFrom(classname))
395 return obj;
396
397 *fLog << dbginf << warn << "Found object '" << name << "' doesn't ";
398 *fLog << "inherit from " << "'" << classname << "' but from '";
399 *fLog << obj->ClassName() << "'" << endl;
400 return NULL;
401}
402
403// --------------------------------------------------------------------------
404//
405// check if the object is in the list or not and check for the correct
406// inheritance
407//
408TObject *MParList::FindObject(const TObject *obj, const char *classname) const
409{
410 TObject *nobj = FindObject(obj);
411
412 if (!nobj)
413 return NULL;
414
415 if (nobj->InheritsFrom(classname))
416 return nobj;
417
418 *fLog << dbginf << warn << "Found object '" << nobj->GetName() << "' ";
419 *fLog << "doesn't inherit from " << "'" << classname << "'" << endl;
420 return NULL;
421}
422
423// --------------------------------------------------------------------------
424//
425// Searches for the tasklist tlist (default: MTaskList) and returns
426// a task with the given name found in this list. If one of both isn't
427// found NULL is returned
428//
429MTask *MParList::FindTask(const char *name, const char *tlist) const
430{
431 TObject *l = FindObject(tlist, "MTaskList");
432 return (MTask*)(l ? l->FindObject(name) : NULL);
433}
434
435// --------------------------------------------------------------------------
436//
437// Find a tasklist which contains a task with name name
438//
439MTaskList *MParList::FindTaskListWithTask(const char *name) const
440{
441 TIter Next(fContainer);
442 TObject *o=0;
443 while ((o=Next()))
444 {
445 MTaskList *l1 = dynamic_cast<MTaskList*>(o);
446 if (!l1)
447 continue;
448
449 MTaskList *l2 = l1->FindTaskList(name);
450 if (l2)
451 return l2;
452 }
453 return 0;
454}
455
456// --------------------------------------------------------------------------
457//
458// Find a tasklist which contains a task task
459//
460MTaskList *MParList::FindTaskListWithTask(const MTask *task) const
461{
462 TIter Next(fContainer);
463 TObject *o=0;
464 while ((o=Next()))
465 {
466 MTaskList *l1 = dynamic_cast<MTaskList*>(o);
467 if (!l1)
468 continue;
469
470 MTaskList *l2 = l1->FindTaskList(task);
471 if (l2)
472 return l2;
473 }
474 return 0;
475}
476
477// --------------------------------------------------------------------------
478//
479// returns the ClassName without anything which is behind that last ';' in
480// string.
481//
482TString MParList::GetClassName(const char *classname)
483{
484 TString cname(classname);
485 const char *semicolon = strrchr(cname, ';');
486
487 if (semicolon)
488 cname.Remove(semicolon-cname);
489
490 return cname;
491}
492
493// --------------------------------------------------------------------------
494//
495// returns the ObjectName. It is created from a class and object name.
496// If no object name is given the objectname is the same than the
497// class name. Leading dots are removed from the object name
498//
499TString MParList::GetObjectName(const char *classname, const char *objname)
500{
501 TString cname(classname);
502 const char *semicolon = strrchr(cname, ';');
503
504 TString oname(objname ? objname : classname);
505
506 if (semicolon)
507 {
508 //
509 // Remove leading dots from objectname (eg. "MMcTrig;5.")
510 //
511 Int_t sz = oname.Sizeof()-2;
512
513 while (sz>=0 && oname[sz]=='.')
514 oname.Remove(sz--);
515 }
516 return oname;
517}
518
519// --------------------------------------------------------------------------
520//
521// Find an object in the list.
522// 'name' is the name of the object you are searching for.
523// If the object doesn't exist we try to create one from the
524// dictionary. If this isn't possible NULL is returned.
525//
526// An object which was created automatically is deleted automatically in
527// the destructor of the parameter list, too. This means, that if an
528// object should survive (eg. Histograms) you MUST create it by yourself
529// and add it to the parameter list.
530//
531// By default (you don't specify an object name) the object name is
532// the same as the classname
533//
534// If the classname (default classname) is of the structure
535// "Name;something" - containing a semicolon - evarything which is
536// after the last appearance of a semicolon is stripped to get the
537// Name of the Class. Normally this is used to number your objects.
538// "Name;1", "Name;2", ... If a semicolon is detected leading dots
539// are stripped from the object-name (eg. "name;5.")
540//
541// In words: Create object of type classname and set its name to objname.
542// If an object with objname already exists return it.
543//
544MParContainer *MParList::FindCreateObj(const char *classname, const char *objname)
545{
546 //
547 // If now object name (name of the object to identify it in the
548 // List) is given use it's classname as the objectname
549 //
550
551 //
552 // Check if the classname is a 'numbered' name (like: "MTime;2")
553 // if so strip the number from the classname.
554 //
555 // Becareful: We check for the last occurance of a ';' only and we
556 // also don't check if a number follows or something else.
557 //
558 // Rem: I use a TString to make the code more readyble and to get
559 // the new object deleted automatically
560 //
561 TString cname = GetClassName(classname);
562 TString oname = GetObjectName(classname, objname);
563
564 //
565 // Try to find a object with this object name which is already
566 // in the List. If we can find one we are done.
567 //
568 MParContainer *pcont = (MParContainer*)FindObject(oname);
569
570 if (pcont)
571 {
572 if (pcont->InheritsFrom(cname))
573 return pcont;
574
575 *fLog << err << "Warning: Object '" << oname << "' found in list doesn't inherit from " << cname << "." << endl;
576 return NULL;
577 }
578
579 //
580 // if object is not existing in the list try to create one
581 //
582 *fLog << inf2 << "Object '" << oname << "' ";
583 if (oname!=cname)
584 *fLog << "[" << cname << "] ";
585 *fLog << "not yet in " << GetName() << "... creating." << endl;
586
587 //
588 // try to get class from root environment
589 //
590 *fLog << err;
591 TClass *cls = GetClass(cname, fLog);
592 if (!cls)
593 return NULL;
594
595 if (!cls->InheritsFrom(MParContainer::Class()))
596 {
597 *fLog << err << dbginf << "Cannot create new instance of class '" << cname << "': " << endl;
598 *fLog << "Class doesn't inherit from MParContainer." << endl;
599 return NULL;
600 }
601
602 //
603 // create the parameter container of the the given class type
604 //
605 pcont = (MParContainer*)cls->New();
606 if (!pcont)
607 {
608 *fLog << err << dbginf << "Cannot create new instance of class '" << cname << "': " << endl;
609 *fLog << " - Class has no default constructor." << endl;
610 *fLog << " - An abstract member functions of a base class is not overwritten." << endl;
611 return NULL;
612 }
613
614 //
615 // Set the name of the container
616 //
617 pcont->SetName(oname);
618
619 //
620 // Now add the object to the parameter list
621 //
622 AddToList(pcont);
623
624 //
625 // The object was automatically created. This makes sure, that such an
626 // object is deleted together with the list
627 //
628 fAutodelete->Add(pcont);
629
630 //
631 // Find an object in the list.
632 // 'name' is the name of the object you are searching for.
633 //
634 return pcont;
635}
636
637// --------------------------------------------------------------------------
638//
639// print some information about the current status of MParList
640//
641void MParList::Print(Option_t *) const
642{
643 *fLog << all << underline << GetDescriptor() << ":" << endl;
644
645 MParContainer *obj = NULL;
646 MIter Next(fContainer);
647 while ((obj=Next()))
648 {
649 *fLog << " " << obj->GetDescriptor();
650 if (fAutodelete->FindObject(obj))
651 *fLog << " <autodel>";
652 *fLog << endl;
653 }
654 *fLog << endl;
655}
656
657// --------------------------------------------------------------------------
658//
659// Sets the flags off all containers in the list (and the list
660// itself) to unchanged
661//
662void MParList::SetReadyToSave(Bool_t flag)
663{
664 fContainer->R__FOR_EACH(MParContainer, SetReadyToSave)(flag);
665 MParContainer::SetReadyToSave(flag);
666}
667
668// --------------------------------------------------------------------------
669//
670// Reset all containers in the list
671//
672void MParList::Reset()
673{
674 fContainer->R__FOR_EACH(MParContainer, Reset)();
675}
676
677// --------------------------------------------------------------------------
678//
679// This finds numbered objects. The objects are returned in a copy of a
680// TObjArray.
681//
682// If from only is given (or to=0) object are assumed numbered
683// from 1 to from.
684//
685TObjArray MParList::FindObjectList(const char *name, UInt_t first, const UInt_t last) const
686{
687 TObjArray list;
688
689 if (first>0 && last<first)
690 {
691 *fLog << err << dbginf << "Cannot create entries backwards (last<first)...skipped." << endl;
692 return list;
693 }
694
695 const UInt_t len = strlen(name);
696
697 char *auxname = new char[len+7];
698 strcpy(auxname, name);
699
700 if (first==0 && last!=0)
701 first = 1;
702
703 //
704 // If only 'from' is specified the number of entries are ment
705 //
706 for (UInt_t i=first; i<=last; i++)
707 {
708 if (first!=0 || last!=0)
709 sprintf(auxname+len, ";%d", i);
710
711 TObject *obj = FindObject(auxname);
712 if (!obj)
713 continue;
714
715 list.AddLast(obj);
716 }
717 delete [] auxname;
718
719 return list;
720}
721
722// --------------------------------------------------------------------------
723//
724// This finds numbered objects. The objects are returned in a copy of a
725// TObjArray. If one of the objects doesn't exist it is created from the
726// meaning of cname and oname (s. FindCreateObj)
727//
728// If from only is given (or to=0) object are assumed numbered
729// from 1 to from.
730//
731TObjArray MParList::FindCreateObjList(const char *cname, UInt_t first, const UInt_t last, const char *oname)
732{
733 TObjArray list;
734
735 if (first>0 && last<first)
736 {
737 *fLog << err << dbginf << "Cannot create entries backwards (last<first)...skipped." << endl;
738 return list;
739 }
740
741 const UInt_t len = strlen(cname);
742
743 char *auxname = new char[len+7];
744 strcpy(auxname, cname);
745
746 //
747 // If only 'from' is specified the number of entries are ment
748 //
749 if (first==0 && last!=0)
750 first = 1;
751
752 for (UInt_t i=first; i<=last; i++)
753 {
754 if (first!=0 || last!=0)
755 sprintf(auxname+len, ";%d", i);
756
757 TObject *obj = FindCreateObj(auxname, oname);
758 if (!obj)
759 break;
760
761 list.AddLast(obj);
762 }
763 delete [] auxname;
764
765 return list;
766}
767
768// --------------------------------------------------------------------------
769//
770// This finds numbered objects. The objects are returned in a copy of a
771// TObjArray. If one of the objects doesn't exist it is created from the
772// meaning of cname and oname (s. FindCreateObj)
773//
774// If from only is given (or to=0) object are assumed numbered
775// from 1 to from.
776//
777// Remark: Because it is static the object are only created and not added to
778// the parameter list. You must also take care of deleting these objects!
779// This function is mainly made for use in root macros. Don't use it in
780// compiled programs if you are not 100% sure what you are doing.
781//
782TObjArray MParList::CreateObjList(const char *cname, UInt_t first, const UInt_t last, const char *)
783{
784 TObjArray list;
785
786 if (first>0 && last<first)
787 {
788 gLog << err << dbginf << "Cannot create entries backwards (last<first)...skipped." << endl;
789 return list;
790 }
791
792 //
793 // try to get class from root environment
794 //
795 gLog << err;
796 TClass *cls = GetClass(cname, &gLog);
797 if (!cls)
798 return list;
799
800 if (!cls->InheritsFrom(MParContainer::Class()))
801 {
802 gLog << err << dbginf << "Cannot create new instance of class '" << cname << "': " << endl;
803 gLog << "Class doesn't inherit from MParContainer." << endl;
804 return list;
805 }
806
807 const UInt_t len = strlen(cname);
808
809 char *auxname = new char[len+7];
810 strcpy(auxname, cname);
811
812 //
813 // If only 'from' is specified the number of entries are ment
814 //
815 if (first==0 && last!=0)
816 first = 1;
817
818 for (UInt_t i=first; i<=last; i++)
819 {
820 if (first!=0 || last!=0)
821 sprintf(auxname+len, ";%d", i);
822
823 //
824 // create the parameter container of the the given class type
825 //
826 MParContainer *pcont = (MParContainer*)cls->New();
827 if (!pcont)
828 {
829 gLog << err << dbginf << "Cannot create new instance of class '" << cname << "' (Maybe no def. constructor)" << endl;
830 return list;
831 }
832
833 //
834 // Set the name of the container
835 //
836 pcont->SetName(auxname);
837
838 //
839 // Add new object to the return list
840 //
841 list.AddLast(pcont);
842 }
843 delete [] auxname;
844
845 return list;
846}
847
848void MParList::SavePrimitive(ostream &out, Option_t *)
849{
850 Bool_t saved = IsSavedAsPrimitive();
851
852 MParContainer::SavePrimitive(out);
853
854 MIter Next(fContainer);
855
856 MParContainer *cont = NULL;
857 while ((cont=Next()))
858 {
859 //
860 // Because it was automatically created don't store its primitive
861 // I guess it will be automatically created again
862 //
863 if (fAutodelete->FindObject(cont) || cont->IsSavedAsPrimitive())
864 continue;
865
866 cont->SavePrimitive(out, "");
867
868 out << " " << GetUniqueName() << ".";
869 out << (cont->InheritsFrom("MTaskList") && saved ? "Replace" : "AddToList");
870 out << "(&" << cont->GetUniqueName() << ");" << endl << endl;
871 }
872}
873
874void MParList::SavePrimitive(ofstream &out, Option_t *o)
875{
876 SavePrimitive(static_cast<ostream&>(out), o);
877}
878
879// --------------------------------------------------------------------------
880//
881// Implementation of SavePrimitive. Used to write the call to a constructor
882// to a macro. In the original root implementation it is used to write
883// gui elements to a macro-file.
884//
885void MParList::StreamPrimitive(ostream &out) const
886{
887 out << " MParList " << GetUniqueName();
888 if (fName!=gsDefName || fTitle!=gsDefTitle)
889 {
890 out << "(\"" << fName << "\"";
891 if (fTitle!=gsDefTitle)
892 out << ", \"" << fTitle << "\"";
893 out <<")";
894 }
895 out << ";" << endl << endl;
896}
897
898// --------------------------------------------------------------------------
899//
900// Adds one TNamed object per object in the list. The TNamed object must
901// be deleted by the user.
902//
903void MParList::GetNames(TObjArray &arr) const
904{
905 MParContainer::GetNames(arr);
906 fContainer->R__FOR_EACH(MParContainer, GetNames)(arr);
907}
908
909// --------------------------------------------------------------------------
910//
911// Sets name and title of each object in the list from the objects in
912// the array.
913//
914void MParList::SetNames(TObjArray &arr)
915{
916 MParContainer::SetNames(arr);
917 fContainer->R__FOR_EACH(MParContainer, SetNames)(arr);
918}
919
920// --------------------------------------------------------------------------
921//
922// Read the contents/setup of a parameter container/task from a TEnv
923// instance (steering card/setup file).
924// The key to search for in the file should be of the syntax:
925// prefix.vname
926// While vname is a name which is specific for a single setup date
927// (variable) of this container and prefix is something like:
928// evtloopname.name
929// While name is the name of the containers/tasks in the parlist/tasklist
930//
931// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
932// Job4.MImgCleanStd.CleaningLevel2: 2.5
933//
934// If this cannot be found the next step is to search for
935// MImgCleanStd.CleaningLevel1: 3.0
936// And if this doesn't exist, too, we search for:
937// CleaningLevel1: 3.0
938//
939// Warning: The programmer is responsible for the names to be unique in
940// all Mars classes.
941//
942Int_t MParList::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
943{
944 if (print)
945 *fLog << all << "MParList::ReadEnv: " << prefix << endl;
946
947 MParContainer *cont = NULL;
948
949 MIter Next(fContainer);
950 while ((cont=Next()))
951 {
952 if (cont->InheritsFrom("MTaskList"))
953 {
954 if (cont->ReadEnv(env, prefix, print)==kERROR)
955 return kERROR;
956 continue;
957 }
958
959 if (cont->TestEnv(env, prefix, print)==kERROR)
960 return kERROR;
961 }
962
963 return kTRUE;
964}
965
966// --------------------------------------------------------------------------
967//
968// Write the contents/setup of a parameter container/task to a TEnv
969// instance (steering card/setup file).
970// The key to search for in the file should be of the syntax:
971// prefix.vname
972// While vname is a name which is specific for a single setup date
973// (variable) of this container and prefix is something like:
974// evtloopname.name
975// While name is the name of the containers/tasks in the parlist/tasklist
976//
977// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
978// Job4.MImgCleanStd.CleaningLevel2: 2.5
979//
980// If this cannot be found the next step is to search for
981// MImgCleanStd.CleaningLevel1: 3.0
982// And if this doesn't exist, too, we search for:
983// CleaningLevel1: 3.0
984//
985// Warning: The programmer is responsible for the names to be unique in
986// all Mars classes.
987//
988Bool_t MParList::WriteEnv(TEnv &env, TString prefix, Bool_t print) const
989{
990 MParContainer *cont = NULL;
991
992 MIter Next(fContainer);
993 while ((cont=Next()))
994 if (!cont->WriteEnv(env, prefix, print))
995 return kFALSE;
996 return kTRUE;
997}
998
999// --------------------------------------------------------------------------
1000//
1001// Can be used to create an iterator over all containers, eg:
1002// MParList plist;
1003// TIter Next(plist); // Be aware: Use a object here rather than a pointer!
1004// TObject *o=0;
1005// while ((o=Next()))
1006// {
1007// [...]
1008// }
1009//
1010MParList::operator TIterator*() const
1011{
1012 return new TOrdCollectionIter(fContainer);
1013}
Note: See TracBrowser for help on using the repository browser.