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

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