ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TBranchBrowsable.cxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id: c5d87ada87b506444a9d0bc027d622273440b891 $
2 // Author: Axel Naumann 14/10/2004
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TBranchBrowsable.h"
13 #include "TBranchElement.h"
14 #include "TBranchObject.h"
15 #include "TMethod.h"
16 #include "TBrowser.h"
17 #include "TTree.h"
18 #include "TLeafObject.h"
19 #include "TClonesArray.h"
20 #include "TVirtualPad.h"
21 #include "TClass.h"
22 #include "TBaseClass.h"
23 #include "TDataMember.h"
24 #include "TStreamerInfo.h"
25 #include "TStreamerElement.h"
27 #include "TRef.h"
28 #include <algorithm>
29 
31 
32 /** \class TVirtualBranchBrowsable
33 
34 TVirtualBranchBrowsable is a base class (not really abstract, but useless
35 by itself) for helper objects that extend TBranch's browsing support.
36 Each registered derived class's generator method is called, which fills
37 all created helper objects into a list which can then be browsed.
38 For details of what these browser helper objects can do, see e.g.
39 TMethodBrowsable, which allows methods to show up in the TBrowser.
40 
41 Only registered helper objects are created. By default, only
42 TMethodBrowsable, TNonSplitBrowsable, and TCollectionPropertyBrowsable
43 are registered (see RegisterDefaultGenerators). You can prevent any of
44 their objects to show up in the browser by unregistering the generator:
45 ~~~ {.cpp}
46  TMethodBrowsable::Unregister()
47 ~~~
48 will stop creating browsable method helper objects from that call on.
49 Note that these helper objects are cached (in TBranch::fBrowsables);
50 already created (and thus cached) browsables will still appear in the
51 browser even after unregistering the corresponding generator.
52 
53 You can implement your own browsable objects and thier generator; see
54 e.g. the simple TCollectionPropertyBrowsable. Note that you will have
55 to register your generator just like any other, and that you should
56 implement the following methods for your own class, mainly for
57 consistency reasons:
58 ~~~ {.cpp}
59  static void Register() {
60  TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables); }
61  static void Unregister() {
62  TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables); }
63 ~~~
64 where GetBrowsables is a static member function of your class, that
65 creates the browsable helper objects, and has the signature
66 ~~~ {.cpp}
67  static Int_t GetBrowsables(TList& list, const TBranch* branch,
68  const TVirtualBranchBrowsable* parent=0);
69 ~~~
70 
71 It has to return the number of browsable helper objects for parent
72 (or, if NULL, for branch) which are added to the list.
73 */
74 
75 std::list<TVirtualBranchBrowsable::MethodCreateListOfBrowsables_t>
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Constructor setting all members according to parameters.
81 
83  Bool_t typeIsPointer,
84  const TVirtualBranchBrowsable* parent /*=0*/):
85 fBranch(branch), fParent(parent), fLeaves(0), fClass(type), fTypeIsPointer(typeIsPointer)
86 {
88  if (!branch)
89  Warning("TVirtualBranchBrowsable", "branch is NULL!");
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Destructor. Delete our leaves.
94 
96 {
97  delete fLeaves;
98 }
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Calls TTree::Draw on the method if return type is not a class;
102 /// otherwise expands returned object's "folder"
103 
105 {
106  if (!fClass
108  && fClass->GetCollectionProxy()->GetType() > 0)) {
109  TString name;
110  GetScope(name);
111 
112  // If this is meant to be run on the collection
113  // we need to "move" the "@" from branch.@member
114  // to branch@.member
115  name.ReplaceAll(".@","@.");
116  name.ReplaceAll("->@","@->");
117 
118  TTree* tree=0;
119  if (!fBranch) {
120  Error("Browse", "branch not set - might access wrong tree!");
121  return;
122  } else tree=fBranch->GetTree();
123  tree->Draw(name, "", b ? b->GetDrawOption() : "");
124  if (gPad) gPad->Update();
125  } else
126  if (GetLeaves()) GetLeaves()->Browse(b);
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Askes all registered generators to fill their browsables into
131 /// the list. The browsables are generated for a given parent,
132 /// or (if 0), for a given branch. The branch is passed down to
133 /// leaves of TVirtualBranchBrowsable, too, as we need to access
134 /// the branch's TTree to be able to traw.
135 
137  const TVirtualBranchBrowsable* parent /* =0 */)
138 {
140  std::list<MethodCreateListOfBrowsables_t>::iterator iGenerator;
141  Int_t numCreated=0;
142  for (iGenerator=fgGenerators.begin(); iGenerator!=fgGenerators.end(); iGenerator++)
143  numCreated+=(*(*iGenerator))(li, branch, parent);
144  return numCreated;
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 /// Check whether the branch (or the parent) contains a collection.
149 /// If it does, set "contained" to the contained type (if we can
150 /// retrieve it) and return the TClass for the collection. Set
151 /// "contained" to the branch's (or parent's) contained object's
152 /// class for non-collections, returning 0.
153 ///
154 /// Only one of "branch" or "parent" can ge given (depending on whether
155 /// we are creating browsable objects for a branch or for another
156 /// browsable object)
157 
159  const TVirtualBranchBrowsable* parent,
160  TClass* &contained)
161 {
162  contained=0;
163  TClass* type=0;
164  if (parent)
165  type=parent->GetClassType();
166  else if (branch) {
167  if (branch->IsA()==TBranchElement::Class()) {
168  // could be a split TClonesArray
169  TBranchElement* be=(TBranchElement*) branch;
170 
171  // this is the contained type - if !=0
172  const char* clonesname=be->GetClonesName();
173  if (clonesname && strlen(clonesname))
174  contained=TClass::GetClass(clonesname);
175 
176  // check if we're in a sub-branch of this class
177  // we can only find out asking the streamer given our ID
178  TStreamerElement *element=0;
179  if (be->GetID()>=0 && be->GetInfo()
180  && (be->GetID() < be->GetInfo()->GetNelement())
181  && be->GetInfo()->IsCompiled()
182  && (element=be->GetInfo()->GetElement(be->GetID()))) {
183  // if contained is set (i.e. GetClonesName was successful),
184  // this element containes the container, otherwise it's the
185  // contained
186  if (contained)
187  // we have all we need
188  return element->GetClassPointer();
189  else
190  type=element->GetClassPointer();
191  } else if (clonesname && strlen(clonesname)) {
192  // we have a clones name, and the TCA is not split:
193  contained=TClass::GetClass(clonesname);
194  return TClass::GetClass(be->GetClassName());
195  } else
196  type=TClass::GetClass(be->GetClassName());
197  } else if (branch->IsA()==TBranchObject::Class()) {
198  // could be an unsplit TClonesArray
199  TBranchObject* bo=(TBranchObject*)branch;
200  const char* clonesname=bo->GetClassName();
201  contained=0;
202  if (!clonesname || !clonesname[0]) return 0;
203  type=TClass::GetClass(clonesname);
204  }
205  } else {
206  ::Warning("TVirtualBranchBrowsable::GetCollectionContainedType", "Neither branch nor parent given!");
207  return 0;
208  }
209 
210  if (!type) return 0;
211 
212  TBranch* branchNonCost=const_cast<TBranch*>(branch);
213  if (type->InheritsFrom(TClonesArray::Class())
214  && branch->IsA()==TBranchObject::Class()
215  && branchNonCost->GetListOfLeaves()
216  && branchNonCost->GetListOfLeaves()->GetEntriesFast()==1) {
217  // load first entry of the branch. Yes, this is bad, and might have
218  // unexpected side effects for the user, esp as already looking at
219  // (and not just drawing) a branch triggeres it.
220  // To prove just how ugly it is, we'll also have to const_cast the
221  // branch...
222  if (branch->GetReadEntry()==-1) branchNonCost->GetEntry(0);
223  // now get element
224  TLeafObject* lo = (TLeafObject*)branchNonCost->GetListOfLeaves()->First();
225  if (lo) {
226  TObject* objContainer = lo->GetObject();
227  if (objContainer && objContainer->IsA()==TClonesArray::Class()) {
228  contained = ((TClonesArray*)objContainer)->GetClass();
229  }
230  }
231  return type;
232  } else if (type->InheritsFrom(TClonesArray::Class())
233  && branch->IsA()==TBranchElement::Class()
234  && branchNonCost->GetListOfLeaves()
235  && branchNonCost->GetListOfLeaves()->GetEntriesFast()==1) {
236  // load first entry of the branch. Yes, this is bad, and might have
237  // unexpected side effects for the user, esp as already looking at
238  // (and not just drawing) a branch triggeres it.
239  // To prove just how ugly it is, we'll also have to const_cast the
240  // branch...
241 
242  //if (branch->GetReadEntry()==-1) branchNonCost->GetEntry(0);
243  // now get element
244  //TLeafObject* lo=(TLeafElement*)branchNonCost->GetListOfLeaves()->First();
245  //TObject* objContainer=(TObject*)((TBranchElement*)branch)->GetValuePointer();
246 
247  //if (objContainer && objContainer->IsA()==TClonesArray::Class())
248  // contained=((TClonesArray*)objContainer)->GetClass();
249 
250  // Currently we can peer into the nested TClonesArray, we need
251  // to update TBranchElement::GetValuePointer.
252  return type;
253  } else if (type->InheritsFrom(TCollection::Class())) {
254  // some other container, and we don't know what the contained type is
255  return type;
256  } else if (type->GetCollectionProxy()) {
257  contained=type->GetCollectionProxy()->GetValueClass();
258  return type;
259  } else if (type->InheritsFrom(TRef::Class()))
260  // we don't do TRefs, so return contained and container as 0
261  return 0;
262  else contained=type;
263  return 0;
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 /// Return list of leaves. If not set up yet we'll create them.
268 
270 {
271  if (!fLeaves) {
272  TList* leaves=new TList();
273  leaves->SetOwner();
274  FillListOfBrowsables(*leaves, GetBranch(), this);
275  const_cast<TVirtualBranchBrowsable*>(this)->fLeaves=leaves;
276  }
277  return fLeaves;
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// returns the list of registered generator methods
282 
283 std::list<TVirtualBranchBrowsable::MethodCreateListOfBrowsables_t>& TVirtualBranchBrowsable::GetRegisteredGenerators()
284 {
285  return fgGenerators;
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////////
289 /// Returns the full name for TTree::Draw to draw *this.
290 /// Recursively appends, starting at the top TBranch,
291 /// all method / object names with proper reference operators (->, .)
292 /// depending on fTypeIsPointer.
293 
295 {
296  if (fParent)
297  fParent->GetScope(scope);
298  else {
299  scope=fBranch->GetName();
300  Ssiz_t pos = scope.First('[');
301  if (pos != kNPOS) {
302  scope.Remove(pos);
303  }
304  if (!scope.EndsWith(".")) scope+=".";
305  const TBranch* mother=fBranch;
306  while (mother != mother->GetMother() && (mother=mother->GetMother())) {
307  TString nameMother(mother->GetName());
308  if (!nameMother.EndsWith(".")) {
309  scope.Prepend(".");
310  scope.Prepend(nameMother);
311  } else {
312  if (mother != mother->GetMother()) {
313  // If the mother is the top level mother
314  // and its ends ends with a ., the name is already
315  // embedded!
316  scope.Prepend(nameMother);
317  }
318  }
319  }
320  }
321  if (GetName() && GetName()[0]=='.')
322  scope+=(GetName()+1);
323  else
324  scope+=GetName();
325  if (fClass && !scope.EndsWith(".")) { // otherwise we're a leaf, and no delimiter is appended
326  if (fTypeIsPointer)
327  scope+="->";
328  else scope+=".";
329  }
330 }
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Adds the default generators. The user can remove any of them as follows:
334 ///
335 /// TMethodBrowsable::Unregister();
336 ///
337 /// which will cause the browser not to show any methods.
338 
340 {
341  if (fgGeneratorsSet) return;
342  // can't call RegisterGenerator - would be recusive infite loop
347 }
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// Adds a generator to be called when browsing branches.
351 /// Called by the Register method, which should be implemented
352 /// for all derived classes (see e.g. TMethodBrowsable::Register())
353 
354 void TVirtualBranchBrowsable::RegisterGenerator(MethodCreateListOfBrowsables_t generator)
355 {
357  // make sure we're not adding another copy
358  fgGenerators.remove(generator);
359  fgGenerators.push_back(generator);
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// Removes a generator from the list of generators to be called when
364 /// browsing branches. The user can remove any of the generators as follows:
365 ///
366 /// TMethodBrowsable::Unregister();
367 ///
368 /// which will cause the browser not to show any methods.
369 
370 void TVirtualBranchBrowsable::UnregisterGenerator(MethodCreateListOfBrowsables_t generator)
371 {
373  fgGenerators.remove(generator);
374 }
375 
377 
378 ////////////////////////////////////////////////////////////////////////////////
379 /// \class TMethodBrowsable
380 ///
381 /// This helper object allows the browsing of methods of objects stored in
382 /// branches. They will be depicted by a leaf (or a branch, in case the method
383 /// returns an object) with a red exclamation mark. Only a subset of all
384 /// methods will be shown in the browser (see IsMethodBrowsable for the
385 /// criteria a method has to satisfy).
386 ///
387 /// Obviously, methods are only available if the library is loaded which
388 /// contains the dictionary for the class to be browsed!
389 ///
390 /// If a branch contains a collection, TMethodBrowsable tries to find out
391 /// what the contained element is (it will only create methods for the
392 /// contained elements, but never for the collection). If it fails to extract
393 /// the type of the contained elements, or if there is no guarantee that the
394 /// type has any other common denominator than TObject (e.g. in the case of
395 /// a TObjArray, which can hold any object deriving from TObject) no methods
396 /// will be added.
397 
398 ////////////////////////////////////////////////////////////////////////////////
399 /// Constructor.
400 /// Links a TBranchElement to a TMethod, allowing the TBrowser to
401 /// browse simple methods.
402 ///
403 /// The c'tor sets the name for a method "Class::Method(params) const"
404 /// to "Method(params)", title to TMethod::GetPrototype
405 
407  const TVirtualBranchBrowsable* parent /* =0 */):
408  TVirtualBranchBrowsable(branch, 0, kFALSE, parent), fMethod(m)
409 {
410  TString name(m->GetName());
411  name+="()";
412  if (name.EndsWith(" const")) name.Remove(name.Length()-6);
413  SetName(name);
414 
415  name=m->GetPrototype();
416  if (m->GetCommentString() && strlen(m->GetCommentString()))
417  name.Append(" // ").Append(m->GetCommentString());
418  SetTitle(name);
419 
420  TString plainReturnType(m->GetReturnTypeName());
421  if (plainReturnType.EndsWith("*")) {
423  plainReturnType.Remove(plainReturnType.Length()-1);
424  plainReturnType.Strip();
425  if(plainReturnType.BeginsWith("const")) {
426  plainReturnType.Remove(0,5);
427  plainReturnType.Strip();
428  }
429  }
430  SetType(TClass::GetClass(plainReturnType));
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////
434 /// Given a class, this methods fills list with TMethodBrowsables
435 /// for the class and its base classes, and returns the number of
436 /// added elements. If called from a TBranch::Browse overload, "branch"
437 /// should be set to the calling TBranch, otherwise "parent" should
438 /// be set to the TVirtualBranchBrowsable being browsed, and branch
439 /// should be the branch of the parent.
440 
442 {
443  if (!cl) return;
444  TList allClasses;
445  allClasses.Add(cl);
446 
447  if (cl->IsLoaded()) {
448  for(TObjLink* lnk=allClasses.FirstLink();
449  lnk; lnk=lnk->Next()) {
450  cl=(TClass*)lnk->GetObject();
451  TList* bases=cl->GetListOfBases();
452  TBaseClass* base;
453  TIter iB(bases);
454  while ((base=(TBaseClass*)iB())) {
455  TClass* bc=base->GetClassPointer();
456  if (bc) allClasses.Add(bc);
457  }
458  }
459  } else {
461  for(int el = 0; el < info->GetElements()->GetEntries(); ++el) {
462  TStreamerElement *element = (TStreamerElement *)info->GetElements()->UncheckedAt(el);
463  if (element->IsBase()) {
464  TClass *bc = element->GetClassPointer();
465  if (bc) allClasses.Add(bc);
466  }
467  }
468  }
469 
470  TList allMethods;
471  TIter iC(&allClasses);
472  while ((cl=(TClass*)iC())) {
473  TList* methods=cl->GetListOfMethods();
474  if (!methods) continue;
475  TMethod* method=0;
476  TIter iM(methods);
477  while ((method=(TMethod*)iM()))
478  if (method && !allMethods.FindObject(method->GetName()))
479  allMethods.Add(method);
480  }
481 
482  TIter iM(&allMethods);
483  TMethod* m=0;
484  while ((m=(TMethod*)iM())) {
486  li.Add(m);
487  }
488  }
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// This methods fills list with TMethodBrowsables
493 /// for the branch's or parent's class and its base classes, and returns
494 /// the number of added elements. If called from a TBranch::Browse
495 /// overload, "branch" should be set to the calling TBranch, otherwise
496 /// "parent" should be set to the TVirtualBranchBrowsable being browsed.
497 
499  const TVirtualBranchBrowsable* parent /*=0*/)
500 {
501  TClass* cl;
502  // we don't care about collections, so only use the TClass argument,
503  // and not the return value
504  GetCollectionContainedType(branch, parent, cl);
505  if (!cl) return 0;
506 
507  TList listMethods;
508  GetBrowsableMethodsForClass(cl, listMethods);
509  TMethod* method=0;
510  TIter iMethods(&listMethods);
511  while ((method=(TMethod*)iMethods())) {
512  li.Add(new TMethodBrowsable(branch, method, parent));
513  }
514  return listMethods.GetSize();
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// A TMethod is browsable if it is const, public and not pure virtual,
519 /// if does not have any parameter without default value, and if it has
520 /// a (non-void) return value.
521 /// A method called *, Get*, or get* will not be browsable if there is a
522 /// persistent data member called f*, _*, or m*, as data member access is
523 /// faster than method access. Examples: if one of fX, _X, or mX is a
524 /// persistent data member, the methods GetX(), getX(), and X() will not
525 /// be browsable.
526 
528 {
529  if (m->GetNargs()-m->GetNargsOpt()==0
530  && (m->Property() & kIsConstant
532  && m->GetReturnTypeName()
533  && strcmp("void",m->GetReturnTypeName())
534  && !strstr(m->GetName(),"DeclFile")
535  && !strstr(m->GetName(),"ImplFile")
536  && strcmp(m->GetName(),"IsA")
537  && strcmp(m->GetName(),"Class")
538  && strcmp(m->GetName(),"CanBypassStreamer")
539  && strcmp(m->GetName(),"Class_Name")
540  && strcmp(m->GetName(),"ClassName")
541  && strcmp(m->GetName(),"Clone")
542  && strcmp(m->GetName(),"DrawClone")
543  && strcmp(m->GetName(),"GetName")
544  && strcmp(m->GetName(),"GetDrawOption")
545  && strcmp(m->GetName(),"GetIconName")
546  && strcmp(m->GetName(),"GetOption")
547  && strcmp(m->GetName(),"GetTitle")
548  && strcmp(m->GetName(),"GetUniqueID")
549  && strcmp(m->GetName(),"Hash")
550  && strcmp(m->GetName(),"IsFolder")
551  && strcmp(m->GetName(),"IsOnHeap")
552  && strcmp(m->GetName(),"IsSortable")
553  && strcmp(m->GetName(),"IsZombie")) {
554 
555  // look for matching data member
556  TClass* cl=m->GetClass();
557  if (!cl) return kTRUE;
558  TList* members=cl->GetListOfDataMembers();
559  if (!members) return kTRUE;
560  const char* baseName=m->GetName();
561  if (!strncmp(m->GetName(), "Get", 3) ||
562  !strncmp(m->GetName(), "get", 3))
563  baseName+=3;
564  if (!baseName[0]) return kTRUE;
565 
566  TObject* mem=0;
567  const char* arrMemberNames[3]={"f%s","_%s","m%s"};
568  for (Int_t i=0; !mem && i<3; i++)
569  mem=members->FindObject(TString::Format(arrMemberNames[i],baseName));
570  return (!mem ||! ((TDataMember*)mem)->IsPersistent());
571  };
572  return kFALSE;
573 }
574 
575 ////////////////////////////////////////////////////////////////////////////////
576 /// Wrapper for the registration method. Needed against MSVC, which
577 /// assigned different addr to the same method, depending on what
578 /// translation unit you're in...
579 
581 {
583 }
584 
585 ////////////////////////////////////////////////////////////////////////////////
586 /// Wrapper for the registration method. Needed against MSVC, which
587 /// assigned different addr to the same method, depending on what
588 /// translation unit you're in...
589 
591 {
593 }
594 
596 
597 ////////////////////////////////////////////////////////////////////////////////
598 /// \class TNonSplitBrowsable
599 ///
600 /// Allows a TBrowser to browse non-split branches as if they were split. The
601 /// generator extracts the necessary information from the streamer info in
602 /// memory (which does not have to be the same as the one on file, in case
603 /// a library was loaded containing the dictionary for this type), i.e. it
604 /// also works without loading the class's library.
605 ///
606 /// Just as with TMethodBrowsables, if the generator finds a collection it
607 /// only takes the contained objects into account, not the collections. If
608 /// it identifies a collection, but cannot extract the contained type, or the
609 /// contained type can be anything deriving from a TObject (like for TObjArray)
610 /// or is not limited at all, no browser helper objects are created.
611 
612 ////////////////////////////////////////////////////////////////////////////////
613 /// Constructor. Creates a TNonSplitBrowsable from a TStreamerElement, containing branch
614 /// and (if applicable) parent TVirtualBranchBrowsable.
615 
617  const TVirtualBranchBrowsable* parent /* =0 */):
618  TVirtualBranchBrowsable(branch, element->GetClassPointer(),
619  element->IsaPointer(), parent)
620 {
621  SetNameTitle(element->GetName(), element->GetTitle());
622 }
623 
624 ////////////////////////////////////////////////////////////////////////////////
625 /// Given either a branch "branch" or a "parent" TVirtualBranchBrowsable, we fill
626 /// "list" with objects of type TNonSplitBrowsable which represent the members
627 /// of class "cl" (and its base classes' members).
628 
630  const TVirtualBranchBrowsable* parent /* =0 */)
631 {
632  // branch has to be unsplit, i.e. without sub-branches
633  if (parent==0
634  && (branch==0 ||
635  (const_cast<TBranch*>(branch)->GetListOfBranches()
636  && const_cast<TBranch*>(branch)->GetListOfBranches()->GetEntries()!=0)
637  )
638  ) {
639  return 0;
640  }
641  // we only expand our own parents
642  //if (parent && parent->IsA()!=TNonSplitBrowsable::Class()) return 0;
643 
644  TClass* clContained=0;
645  GetCollectionContainedType(branch, parent, clContained);
646  TVirtualStreamerInfo* streamerInfo= clContained?clContained->GetStreamerInfo():0;
647  if (!streamerInfo
648  || !streamerInfo->GetElements()
649  || !streamerInfo->GetElements()->GetSize()) return 0;
650 
651  if (!branch && parent) branch=parent->GetBranch();
652 
653  // we simply add all of our and the bases' members into one big list
654  TList myStreamerElementsToCheck;
655  myStreamerElementsToCheck.AddAll(streamerInfo->GetElements());
656 
657  Int_t numAdded=0;
658  TStreamerElement* streamerElement=0;
659  for (TObjLink *link = myStreamerElementsToCheck.FirstLink();
660  link;
661  link = link->Next() ) {
662  streamerElement = (TStreamerElement*)link->GetObject();
663  if (streamerElement->IsBase()) {
664  // this is a base class place holder
665  // continue with the base class's streamer info
666  TClass* base=streamerElement->GetClassPointer();
667  if (!base || !base->GetStreamerInfo()) continue;
668 
669  // add all of the base class's streamer elements
670  // (which in turn can be a base, which will be
671  // unfolded in a later iteration) to the list
672  TObjArray* baseElements=base->GetStreamerInfo()->GetElements();
673  if (!baseElements) continue;
674  TIter iBaseSE(baseElements);
675  TStreamerElement* baseSE=0;
676  while ((baseSE=(TStreamerElement*)iBaseSE()))
677  // we should probably check whether we're replacing something here...
678  myStreamerElementsToCheck.Add(baseSE);
679  } else if (!strcmp(streamerElement->GetName(),"This")
680  && !strcmp(clContained->GetName(), streamerElement->GetTypeName())) {
681  // this is a collection of the real elements.
682  // So get the class ptr for these elements...
683  TClass* clElements=streamerElement->GetClassPointer();
684  TVirtualCollectionProxy* collProxy=clElements?clElements->GetCollectionProxy():0;
685  clElements=collProxy?collProxy->GetValueClass():0;
686  if (!clElements) continue;
687 
688  // now loop over the class's streamer elements
689  streamerInfo = clElements->GetStreamerInfo();
690  if (streamerInfo) {
691  TIter iElem(streamerInfo->GetElements());
692  TStreamerElement* elem=0;
693  while ((elem=(TStreamerElement*)iElem())) {
694  TNonSplitBrowsable* nsb=new TNonSplitBrowsable(elem, branch, parent);
695  li.Add(nsb);
696  numAdded++;
697  }
698  } else {
699  ::Error("TNonSplitBrowsable::GetBrowsables",
700  "Missing the StreamerInfo for the class \"%s\" for the branch \"%s\" in the TTree \"%s\".",
701  clElements->GetName(), branch->GetName(), branch->GetTree()->GetName());
702  }
703  } else {
704  // we have a basic streamer element
705  TNonSplitBrowsable* nsb=new TNonSplitBrowsable(streamerElement, branch, parent);
706  li.Add(nsb);
707  numAdded++;
708  }
709  }
710  return numAdded;
711 }
712 
713 ////////////////////////////////////////////////////////////////////////////////
714 /// Wrapper for the registration method. Needed against MSVC, which
715 /// assigned different addr to the same method, depending on what
716 /// translation unit you're in...
717 
719 {
721 }
722 
723 ////////////////////////////////////////////////////////////////////////////////
724 /// Wrapper for the registration method. Needed against MSVC, which
725 /// assigned different addr to the same method, depending on what
726 /// translation unit you're in...
727 
729 {
731 }
732 
734 
735 ////////////////////////////////////////////////////////////////////////////////
736 /// \class TCollectionPropertyBrowsable
737 ///
738 /// A tiny browser helper object (and its generator) for adding a virtual
739 /// (as in "not actually part of the class", not in C++ virtual) "@size()"
740 /// method to a collection. For all collections that derive from
741 /// TCollection, or have a TVirtualCollectionProxy associated with them,
742 /// a leaf is created that allows access to the number of elements in the
743 /// collection. For TClonesArrays and types with an associated
744 /// TVirtualCollectionProxy, this forwards to TTreeFormula's
745 /// "@branch.size()" functionality. For all other collections, a method call
746 /// to the appropriate collection's member function is executed when drawing.
747 ///
748 /// These objects are of course only created for elements containing a
749 /// collection; the generator has no effect on any other elements.
750 
751 ////////////////////////////////////////////////////////////////////////////////
752 /// Browses a TCollectionPropertyBrowsable. The only difference to
753 /// the generic TVirtualBranchBrowsable::Browse is our fDraw
754 
756 {
757  GetBranch()->GetTree()->Draw(GetDraw(), "", b ? b->GetDrawOption() : "");
758  if (gPad) gPad->Update();
759 }
760 
761 ////////////////////////////////////////////////////////////////////////////////
762 /// If the element to browse (given by either parent of branch) contains
763 /// a collection (TClonesArray or something for which a TVirtualCollectionProxy
764 /// exists), we will add some special objects to the browser. For now there is
765 /// just one object "@size", returning the size of the collection (as in
766 /// std::list::size(), or TClonesArray::GetEntries()).
767 /// The objects we create are simply used to forward strings (like "@size") to
768 /// TTreeFormula via our Browse method. These strings are stored in fName.
769 
771  const TVirtualBranchBrowsable* parent /* =0 */)
772 {
773  TClass* clContained=0;
774  TClass* clCollection=GetCollectionContainedType(branch, parent, clContained);
775  if (!clCollection || !clContained) return 0;
776 
777  // Build the fDraw string. Start with our scope.
778  TString scope;
779  if (parent) {
780  parent->GetScope(scope);
781  branch=parent->GetBranch();
782  } else if (branch){
783  scope=branch->GetName();
784  scope+=".";
785  const TBranch* mother=branch;
786  while (mother != mother->GetMother() && (mother=mother->GetMother())) {
787  TString nameMother(mother->GetName());
788  if (!nameMother.EndsWith(".")) {
789  scope.Prepend(".");
790  scope.Prepend(nameMother);
791  } else {
792  if (mother != mother->GetMother()) {
793  // If the mother is the top level mother
794  // and its ends ends with a ., the name is already
795  // embedded!
796  scope.Prepend(nameMother);
797  }
798  }
799  }
800  } else {
801  ::Warning("TCollectionPropertyBrowsable::GetBrowsables", "Neither branch nor parent is set!");
802  return 0;
803  }
804 
805  // remove trailing delimiters
806  if (scope.EndsWith(".")) scope.Remove(scope.Length()-1, 1);
807  else if (scope.EndsWith("->")) scope.Remove(scope.Length()-2, 2);
808 
809  // now prepend "@" to the last element of the scope,
810  // to access the collection and not its containees
811  Ssiz_t lastDot=scope.Last('.');
812  Ssiz_t lastArrow=scope.Last('>'); // assuming there's no branch name containing ">"...
813  Ssiz_t lastPart=lastDot;
814  if (lastPart==kNPOS || (lastArrow!=kNPOS && lastPart<lastArrow))
815  lastPart=lastArrow;
816  if (lastPart==kNPOS) lastPart=0;
817  else lastPart++;
818 
819  TString size_title("size of ");
820  size_title += clCollection->GetName();
821  if (clContained) {
822  size_title += " of ";
823  size_title += clContained->GetName();
824  }
825 
826  if (clCollection->GetCollectionProxy() || clCollection==TClonesArray::Class()) {
827  // the collection is one for which TTree::Draw supports @coll.size()
828 
830  if ( clCollection->GetCollectionProxy() &&
831  ( (clCollection->GetCollectionProxy()->GetValueClass()==0)
832  ||(clCollection->GetCollectionProxy()->GetValueClass()->GetCollectionProxy()!=0
833  && clCollection->GetCollectionProxy()->GetValueClass()->GetCollectionProxy()->GetValueClass()==0)
834  )) {
835  // If the contained type is not a class, we need an explitcit handle to get to the data.
836  cpb = new TCollectionPropertyBrowsable("values", "values in the container",
837  scope, branch, parent);
838  li.Add(cpb);
839  }
840  scope.Insert(lastPart, "@");
841  cpb = new TCollectionPropertyBrowsable("@size", size_title,
842  scope+".size()", branch, parent);
843  li.Add(cpb);
844  return 1;
845  } // if a collection proxy or TClonesArray
846  else if (clCollection->InheritsFrom(TCollection::Class())) {
847  // generic TCollection - we'll build size() ourselves, by mapping
848  // it to the proper member function of the collection
849  if (clCollection->InheritsFrom(TObjArray::Class()))
850  scope+="@.GetEntries()";
851  else scope+="@.GetSize()";
853  new TCollectionPropertyBrowsable("@size", size_title, scope, branch, parent);
854  li.Add(cpb);
855  return 1;
856  }
857  return 0;
858 }
859 
860 ////////////////////////////////////////////////////////////////////////////////
861 /// Wrapper for the registration method. Needed against MSVC, which
862 /// assigned different addr to the same method, depending on what
863 /// translation unit you're in...
864 
866 {
868 }
869 
870 ////////////////////////////////////////////////////////////////////////////////
871 /// Wrapper for the registration method. Needed against MSVC, which
872 /// assigned different addr to the same method, depending on what
873 /// translation unit you're in...
874 
876 {
878 }
879 
881 
882 ////////////////////////////////////////////////////////////////////////////////
883 /// \class TCollectionMethodBrowsable
884 ///
885 /// TCollectionMethodBrowsable extends TCollectionPropertyBrowsable by showing
886 /// all methods of the collection itself. If none are available - e.g. for STL
887 /// classes like std::list, a TVirtualBranchBrowsable object is reated instead.
888 /// The methods' names will have a "@" prepended, to distinguish them from the
889 /// contained elements' methods.
890 ///
891 /// This browser helper object is not part of the default list of registered
892 /// generators (see TVirtualBranchBrowsable::RegisterDefaultGenerators()).
893 /// If you want to use it, you should call
894 /// TCollectionMethodBrowsable::Register();
895 /// As it extends the functionality of TVirtualBranchBrowsable, one might want
896 /// to unregister the generator of the "@size()" method by calling
897 /// TCollectionPropertyBrowsable::Unregister();
898 
899 ////////////////////////////////////////////////////////////////////////////////
900 /// Contructor, see TMethodBrowsable's constructor.
901 /// Prepends "@" to the name to make this method work on the container.
902 
904  const TVirtualBranchBrowsable* parent /*=0*/):
905 TMethodBrowsable(branch, m, parent)
906 {
907  SetName(TString("@")+GetName());
908 }
909 
910 ////////////////////////////////////////////////////////////////////////////////
911 /// This methods fills list with TMethodBrowsables
912 /// for the branch's or parent's collection class and its base classes,
913 /// and returns the number of added elements. If called from a TBranch::Browse
914 /// overload, "branch" should be set to the calling TBranch, otherwise
915 /// "parent" should be set to the TVirtualBranchBrowsable being browsed.
916 
918  const TVirtualBranchBrowsable* parent /*=0*/)
919 {
920  TClass* clContained=0;
921  // we don't care about the contained class, but only about the collections,
922  TClass* clContainer=GetCollectionContainedType(branch, parent, clContained);
923  if (!clContainer || !clContained) return 0;
924 
925  TList listMethods;
926  GetBrowsableMethodsForClass(clContainer, listMethods);
927  TMethod* method=0;
928  TIter iMethods(&listMethods);
929  while ((method=(TMethod*)iMethods()))
930  li.Add(new TCollectionMethodBrowsable(branch, method, parent));
931 
932  // if we have no methods, and if the class has a collection proxy, just add
933  // the corresponding TCollectionPropertyBrowsable instead.
934  // But only do that if TCollectionPropertyBrowsable is not generatated anyway
935  // - we don't need two of them.
936  if (!listMethods.GetSize() && clContainer->GetCollectionProxy()) {
937  std::list<MethodCreateListOfBrowsables_t>& listGenerators=GetRegisteredGenerators();
938  std::list<MethodCreateListOfBrowsables_t>::iterator iIsRegistered
939  = std::find(listGenerators.begin(), listGenerators.end(), &TCollectionPropertyBrowsable::GetBrowsables);
940  if (iIsRegistered==listGenerators.end()) {
942  return 1;
943  }
944  }
945  return listMethods.GetSize();
946 }
947 
948 ////////////////////////////////////////////////////////////////////////////////
949 /// Wrapper for the registration method. Needed against MSVC, which
950 /// assigned different addr to the same method, depending on what
951 /// translation unit you're in...
952 
954 {
956 }
957 
958 ////////////////////////////////////////////////////////////////////////////////
959 /// Wrapper for the registration method. Needed against MSVC, which
960 /// assigned different addr to the same method, depending on what
961 /// translation unit you're in...
962 
964 {
966 }
static void Unregister()
Wrapper for the registration method.
Long64_t GetReadEntry() const
Definition: TBranch.h:169
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:851
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3368
An array of TObjects.
Definition: TObjArray.h:39
Int_t GetNelement() const
void GetScope(TString &scope) const
Returns the full name for TTree::Draw to draw *this.
static void RegisterDefaultGenerators()
Adds the default generators.
Int_t GetID() const
const char * GetTypeName() const
Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TBrowser.h:108
A Branch for the case of an object.
Definition: TBranchObject.h:28
Ssiz_t Length() const
Definition: TString.h:390
virtual TClass * GetValueClass() const =0
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:33
A TLeaf for a general object derived from TObject.
Definition: TLeafObject.h:35
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Definition: TBaseClass.cxx:63
const char * GetReturnTypeName() const
Get full type description of function return type, e,g.: "class TDirectory*".
Definition: TFunction.cxx:140
static Int_t GetBrowsables(TList &list, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
This methods fills list with TMethodBrowsables for the branch's or parent's collection class and its ...
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
ClassImp(TVirtualBranchBrowsable)
static Int_t GetBrowsables(TList &list, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
This methods fills list with TMethodBrowsables for the branch's or parent's class and its base classe...
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3459
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
static void Register()
Wrapper for the registration method.
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
TString & Prepend(const char *cs)
Definition: TString.h:604
virtual EDataType GetType() const =0
virtual void SetNameTitle(const char *name, const char *title)
Change (i.e. set) all the TNamed parameters (name and title).
Definition: TNamed.cxx:142
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:592
const TVirtualBranchBrowsable * fParent
A tiny browser helper object (and its generator) for adding a virtual (as in "not actually part of th...
virtual const char * GetClonesName() const
void SetType(TClass *type)
static Int_t FillListOfBrowsables(TList &list, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
Askes all registered generators to fill their browsables into the list.
ClassImp(RooList) TObjOptLink *RooList TObjLink * link
Find the link corresponding to the named object in this list.
Definition: RooList.cxx:49
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2321
const TBranch * GetBranch() const
static void GetBrowsableMethodsForClass(TClass *cl, TList &list)
Given a class, this methods fills list with TMethodBrowsables for the class and its base classes...
static void Unregister()
Wrapper for the registration method.
TNonSplitBrowsable(const TStreamerElement *element, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
Constructor.
void Class()
Definition: Class.C:29
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
virtual void AddAll(const TCollection *col)
TCollectionMethodBrowsable(const TBranch *branch, TMethod *m, const TVirtualBranchBrowsable *parent=0)
Contructor, see TMethodBrowsable's constructor.
TClass * fClass
pointer to the foreign object
TObject * First() const
Return the object in the first slot.
Definition: TObjArray.cxx:471
virtual const char * GetCommentString()
Returns a comment string from the class declaration.
Definition: TMethod.cxx:105
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
A doubly linked list.
Definition: TList.h:47
static TClass * GetCollectionContainedType(const TBranch *b, const TVirtualBranchBrowsable *parent, TClass *&contained)
Check whether the branch (or the parent) contains a collection.
static void Register()
Wrapper for the registration method.
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
Int_t GetNargsOpt() const
Number of function optional (default) arguments.
Definition: TFunction.cxx:174
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2207
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4256
static Bool_t IsMethodBrowsable(const TMethod *m)
A TMethod is browsable if it is const, public and not pure virtual, if does not have any parameter wi...
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1533
static void RegisterGenerator(MethodCreateListOfBrowsables_t generator)
Adds a generator to be called when browsing branches.
TMarker * m
Definition: textangle.C:8
TCollectionMethodBrowsable extends TCollectionPropertyBrowsable by showing all methods of the collect...
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranchObject.h:46
static Int_t GetBrowsables(TList &list, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
Given either a branch "branch" or a "parent" TVirtualBranchBrowsable, we fill "list" with objec...
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
Definition: TBranch.cxx:1199
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:183
static void Unregister()
Wrapper for the registration method.
virtual TObjLink * FirstLink() const
Definition: TList.h:101
static Bool_t fgGeneratorsSet
TMethodBrowsable(const TBranch *branch, TMethod *m, const TVirtualBranchBrowsable *parent=0)
Constructor.
TVirtualBranchBrowsable is a base class (not really abstract, but useless by itself) for helper objec...
TTree * GetTree() const
Definition: TBranch.h:183
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:35
A Branch for the case of an object.
void SetTypeIsPointer(Bool_t set=kTRUE)
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5436
int Ssiz_t
Definition: RtypesCore.h:63
TClass * GetClass() const
Definition: TMethod.h:57
tuple tree
Definition: tree.py:24
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual const char * GetPrototype() const
Returns the prototype of a function as defined by CINT, or 0 in case of error.
Definition: TFunction.cxx:245
virtual TObjArray * GetElements() const =0
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
TClass * GetClassType() const
int type
Definition: TGX11.cxx:120
void Browse(TBrowser *b)
Calls TTree::Draw on the method if return type is not a class; otherwise expands returned object's "f...
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:360
TCollectionPropertyBrowsable(const char *name, const char *title, const char *draw, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
TObject * GetObject() const
Definition: TLeafObject.h:52
void Browse(TBrowser *b)
Browse this collection (called by TBrowser).
TObjArray * GetListOfLeaves()
Definition: TBranch.h:178
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2801
TList * GetLeaves() const
Return list of leaves. If not set up yet we'll create them.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2730
#define name(a, b)
Definition: linkTestLib0.cpp:5
Mother of all ROOT objects.
Definition: TObject.h:58
static void Register()
Wrapper for the registration method.
An array of clone (identical) objects.
Definition: TClonesArray.h:32
static Int_t GetBrowsables(TList &list, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
If the element to browse (given by either parent of branch) contains a collection (TClonesArray or so...
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:40
TStreamerElement * GetElement(Int_t id) const
#define gPad
Definition: TVirtualPad.h:288
static void Unregister()
Wrapper for the registration method.
A TTree object has a header with a name and a title.
Definition: TTree.h:98
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4498
static std::list< MethodCreateListOfBrowsables_t > fgGenerators
static void Register()
Wrapper for the registration method.
void Browse(TBrowser *b)
Browses a TCollectionPropertyBrowsable.
A TTree is a list of TBranches.
Definition: TBranch.h:58
Abstract Interface class describing Streamer information for one class.
static std::list< MethodCreateListOfBrowsables_t > & GetRegisteredGenerators()
returns the list of registered generator methods
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TList * GetListOfMethods(Bool_t load=kTRUE)
Return list containing the TMethods of a class.
Definition: TClass.cxx:3508
~TVirtualBranchBrowsable()
Destructor. Delete our leaves.
TVirtualBranchBrowsable(const TBranch *b, TClass *type, Bool_t typeIsPointer, const TVirtualBranchBrowsable *parent=0)
Constructor setting all members according to parameters.
Allows a TBrowser to browse non-split branches as if they were split.
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:453
const char * GetDraw() const
static void UnregisterGenerator(MethodCreateListOfBrowsables_t generator)
Removes a generator from the list of generators to be called when browsing branches.
This helper object allows the browsing of methods of objects stored in branches.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904