Hi Rene, as I promised you in Chicago, I send you another small class. This class provide automatic browsing of objects. User can define his Browse method as: void TObject::Browse(TBrowser *b) { TAutoBrowse::Browse(this,b); } It is enough to browse complex object. This method is based on ShowMember function. Actually, if define such Browse method for TObject, all objects inherited from TObject will be automatically browsable. But it is your decision. We, in STAR use this method to browse very complicated objects, so it is well debuged. Victor -- Victor M. Perevoztchikov perev@bnl.gov perev@vxcern.cern.ch Brookhaven National Laboratory MS 510A PO Box 5000 Upton NY 11973-5000 tel office : 631-344-7894; fax 631-344-4206; home 631-345-2690 #ifndef _TAUTOBROWSE_ #define _TAUTOBROWSE_ 2001 class TObject; class TAutoBrowse { protected: TAutoBrowse(){}; ~TAutoBrowse(){}; public: static Int_t Browse(TObject *obj, TBrowser *browser); }; #endif // _STAUTOBROWSE_ #include <stdio.h> #include <stdlib.h> #include "TROOT.h" #include "TClass.h" #include "TBaseClass.h" #include "TDataMember.h" #include "TMethod.h" #include "TMethodArg.h" #include "TDataType.h" #include "Api.h" #include "TBrowser.h" #include "TMemberInspector.h" #include "TError.h" #include "TAutoBrowse.h" class MyAutoInspector : public TMemberInspector { // // class MyAutoInspector is local for this file public: MyAutoInspector(TBrowser *b){fBrowser=b;fCount=0;}; virtual ~MyAutoInspector(){}; virtual void Inspect(TClass* cl, const char* parent, const char* name, void* addr); Int_t fCount; TBrowser *fBrowser; }; //______________________________________________________________________________ void MyAutoInspector::Inspect(TClass* kl, const char* tit , const char* name, void* addr) { if(tit && strchr(tit,'.')) return ; if (fCount && !fBrowser) return; TString ts; if (!kl) return; if (*(kl->GetName()) == 'T') return; if (*name == '*') name++; int ln = strcspn(name,"[ "); TString iname(name,ln); G__ClassInfo *classInfo = kl->GetClassInfo(); if (!classInfo) return; G__ClassInfo &cl = *classInfo; // Browse data members G__DataMemberInfo m(cl); TString mname; int found=0; while (m.Next()) { // MemberLoop mname = m.Name(); mname.ReplaceAll("*",""); if ((found = (iname==mname))) break; } assert(found); // we skip: non TObjects // - the member G__virtualinfo inserted by the CINT RTTI system long prop = m.Property() | m.Type()->Property(); if (prop & G__BIT_ISSTATIC) return; if (prop & G__BIT_ISFUNDAMENTAL) return; if (prop & G__BIT_ISENUM) return; if (strcmp(m.Type()->Fullname(),"TObject") && !m.Type()->IsBase("TObject")) return; if (mname == "G__virtualinfo") return; int size = sizeof(void*); if (!(prop&G__BIT_ISPOINTER)) size = m.Type()->Size(); int nmax = 1; if (prop & G__BIT_ISARRAY) { for (int dim = 0; dim < m.ArrayDim(); dim++) nmax *= m.MaxIndex(dim); } for(int i=0; i<nmax; i++) { char *ptr = (char*)addr + i*size; TObject *obj = (prop&G__BIT_ISPOINTER) ? *((TObject**)ptr) : (TObject*)ptr; if (!obj) continue; fCount++; if (!fBrowser) return; const char *bwname = obj->GetName(); if (!bwname[0] || strcmp(bwname,obj->ClassName())==0) { bwname = name; if (strcmp(bwname,"fOrBrowser")==0) { ts.Replace(0,999,tit,strlen(tit)-1); bwname = (const char*)ts; } else { int l = strcspn(bwname,"[ "); if (bwname[l]=='[') { char cbuf[12]; sprintf(cbuf,"[%02d]",i); ts.Replace(0,999,bwname,l); ts += cbuf; bwname = (const char*)ts; } } } fBrowser->Add(obj,bwname); } } //______________________________________________________________________________ Int_t TAutoBrowse::Browse(TObject *obj,TBrowser *browser) { // Browse external object inherited from TObject // It passes through inheritance tree and calls TBrowser::Add // in appropriate cases if(!obj) return 0; char cbuf[1000]; *cbuf=0; MyAutoInspector insp(browser); ((TObject*)obj)->ShowMembers(insp,cbuf); return insp.fCount; }
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:38 MET