source: trunk/MagicSoft/Mars/mbase/MParList.cc @ 8642

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