Logo ROOT   6.12/07
Reference Guide
TRef.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Rene Brun 28/09/2001
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 /** \class TRef
13 \ingroup Base
14 
15 Persistent Reference link to a TObject
16 A TRef is a lightweight object pointing to any TObject.
17 This object can be used instead of normal C++ pointers in case
18 
19  - the referenced object R and the pointer P are not written to the same file
20  - P is read before R
21  - R and P are written to different Tree branches
22 
23 When a top level object (eg Event *event) is a tree/graph of many objects,
24 the normal ROOT Streaming mechanism ensures that only one copy of each object
25 in the tree/graph is written to the output buffer to avoid circular
26 dependencies.
27 
28 However if the object event is split into several files or into several
29 branches of one or more Trees, normal C++ pointers cannot be used because
30 each I/O operation will write the referenced objects.
31 
32 When a TRef is used to point to a TObject *robj, for example in a class with
33 ~~~ {.cpp}
34  TRef fRef;
35 ~~~
36 one can do:
37 ~~~ {.cpp}
38  fRef = robj; //to set the pointer
39 ~~~
40 This TRef and robj can be written with two different I/O calls
41 in the same or different files, in the same or different branches of a Tree.
42 
43 If the TRef is read and the referenced object has not yet been read,
44 the TRef will return a null pointer. As soon as the referenced object
45 will be read, the TRef will point to it. If the referenced object is
46 contained in a TTree it can be auto-loaded using the TBranchRef mechanism,
47 which is set up by simply calling TTree::BranchRef().
48 
49 TRef also supports the complex situation where a TFile is updated
50 multiple times on the same machine or a different machine.
51 
52 ## How does it work
53 
54 A TRef is itself a TObject with an additional transient pointer fPID.
55 When the statement fRef = robj is executed, the following actions happen:
56 
57  - The pointer fPID is set to the current TProcessID.
58  - The current ObjectNumber (see below) is incremented by one.
59  - robj::fUniqueID is set to ObjectNumber.
60  - In the fPID object, the element fObjects[ObjectNumber] is set to robj
61  - ref::fUniqueID is also set to ObjectNumber.
62 
63 After having set fRef, one can immediately return the value of robj
64 using fRef.GetObject(). This function returns directly fObjects[fUniqueID]
65 from the fPID object.
66 
67 When the TRef is written, the process id number pidf of fPID is written
68 in addition to the TObject part of TRef (fBits,fUniqueID).
69 
70 When the TRef is read, its pointer fPID is set to the value
71 stored in the TObjArray of TFile::fProcessIDs (fProcessIDs[pidf]).
72 The pidf is stored as a UShort_t limiting a file to 65535 distinct
73 ProcessID objects.
74 
75 The pidf is stored in the bits 24->31 of the fUniqueID of the TRef.
76 This implies that the number of TRefs in a single ProcessID should not
77 exceed 2**24 = 16777216. For pidf greater than 254, the value 0xff is
78 stored in those bits and we use the table TProcessID::fgObjPIDs which
79 links the referenced object's address to its ProcessID.
80 
81 See section "ObjectNumber" below for a recipe to minimize the object count.
82 If the object-number exceeds this limit, it could be the sign that:
83 
84  - The object count is never reset (see below)
85  - TRef is misused.
86 
87 When a referenced object robj is written, TObject::Streamer writes
88 in addition to the standard (fBits,fUniqueID) the pidf.
89 When this robj is read by TObject::Streamer, the pidf is read.
90 At this point, robj is entered into the table of objects of the TProcessID
91 corresponding to pidf.
92 
93 ### WARNING1:
94 If MyClass is the class of the referenced object, The TObject
95 part of MyClass must be Streamed. One should not
96 call MyClass::Class()->IgnoreTObjectStreamer()
97 
98 ### WARNING2:
99 A TRef cannot point to another TRef.
100 
101 ## ObjectNumber
102 
103 When an object is referenced (see TRef assignment operator or TRefArray::Add)
104 a unique identifier is computed and stored in both the fUniqueID of the
105 referenced and referencing object. This uniqueID is computed by incrementing
106 by one the static global in TProcessID::fgNumber. fUniqueID is some sort of
107 serial object number in the current session. One can retrieve at any time
108 the current value of fgNumber by calling the static function TProcessID::GetObjectCount
109 or set this number via TProcessID::SetObjectCount.
110 
111 To avoid a growing table of fObjects in TProcessID, in case, for example,
112 one processes many events in a loop, it might be necessary to reset the
113 ObjectNumber at the end of processing of one event. See an example
114 in $ROOTSYS/test/Event.cxx (look at function Build).
115 
116 The value of ObjectNumber (say saveNumber=TProcessID::GetObjectCount()) may be
117 saved at the beginning of one event and reset to this original value
118 at the end of the event via TProcessID::SetObjectCount(saveNumber). These
119 actions may be stacked.
120 
121 ## Action on Demand
122 
123 The normal behaviour of a TRef has been described above. In addition,
124 TRef supports also "Actions on Demand". It may happen that the object
125 referenced is not yet in memory, on a separate file or not yet computed.
126 In this case TRef is able to automatically execute an action:
127 
128  - call to a compiled function (static function of member function)
129  - call to an interpreted function
130  - execution of a C++ script
131 
132 How to select this option?
133 In the definition of the TRef data member in the original class, do:
134 ~~~ {.cpp}
135  TRef fRef; //EXEC:execName. points to something
136 ~~~
137 When the special keyword "EXEC:" is found in the comment field of the member,
138 the next string is assumed to be the name of a TExec object.
139 When a file is connected, the dictionary of the classes on the file
140 is read in memory (see TFile::ReadStreamerInfo). When the TStreamerElement
141 object is read, a TExec object is automatically created with the name
142 specified after the keyword "EXEC:" in case a TExec with a same name does
143 not already exist.
144 
145 The action to be executed via this TExec can be specified with:
146 
147  - a call to the TExec constructor, if the constructor is called before
148  opening the file.
149  - a call to TExec::SetAction at any time.
150  One can compute a pointer to an existing TExec with a name with:
151 ~~~ {.cpp}
152  TExec *myExec = gROOT->GetExec(execName);
153  myExec->SetAction(actionCommand);
154 ~~~
155  where actionCommand is a string containing a C++ instruction. Examples:
156 ~~~ {.cpp}
157  myExec->SetAction("LoadHits()");
158  myExec->SetAction(".x script.C");
159 ~~~
160 
161 When a TRef is dereferenced via TRef::GetObject, its TExec will be
162 automatically executed. In the function/script being executed, one or more
163 of the following actions can be executed:
164 
165  - load a file containing the referenced object. This function typically
166  looks in the file catalog (GRID).
167  - compute a pointer to the referenced object and communicate this pointer
168  back to the calling function TRef::GetObject via:
169 ~~~ {.cpp}
170  TRef::SetStaticObject(object).
171 ~~~
172  When the TExec is called, it has access to the dereferencing TRef
173  by calling GetStaticObject() (TRef::GetObject() sets fgObject to "this"
174  before the call to TExec). This can be useful for accessing the TRef's
175  fUniqueID.
176 
177 As soon as an object is returned to GetObject, the fUniqueID of the TRef is set
178 to the fUniqueID of the referenced object. At the next call to GetObject,
179 the pointer stored in fPid:fObjects[fUniqueID] will be returned directly.
180 
181 An example of action on demand is shown in $ROOTSYS/test/Event.h with
182 the member:
183 ~~~ {.cpp}
184  TRef fWebHistogram; //EXEC:GetWebHistogram
185 ~~~
186 When calling fWebHistogram.GetObject(), the function GetObject
187 will automatically invoke a script GetWebHistogram.C via the interpreter.
188 
189 An example of a GetWebHistogram.C script is shown below
190 ~~~ {.cpp}
191  void GetWebHistogram() {
192  TFile *f= TFile::Open("http://root.cern.ch/files/pippa.root");
193  f->cd("DM/CJ");
194  TH1 *h6 = (TH1*)gDirectory->Get("h6");
195  h6->SetDirectory(0);
196  delete f;
197  TRef::SetStaticObject(h6);
198  }
199 ~~~
200 In the above example, a call to fWebHistogram.GetObject() executes the
201 script with the function GetWebHistogram. This script connects a file
202 with histograms: pippa.root on the ROOT Web site and returns the object h6
203 to TRef::GetObject.
204 
205 Note that if the definition of the TRef fWebHistogram had been:
206 ~~~ {.cpp}
207  TRef fWebHistogram; //EXEC:GetWebHistogram()
208 ~~~
209 then, the compiled or interpreted function GetWebHistogram() would have
210 been called instead of the C++ script GetWebHistogram.C
211 
212 ## Special case of a TRef pointing to an object with a TUUID
213 
214 If the referenced object has a TUUID, its bit kHasUUID has been set.
215 This case is detected by the TRef assignment operator.
216 (For example, TFile and TDirectory have a TUUID)
217 The TRef fPID points directly to the single object TProcessUUID (deriving
218 from TProcessID) and managing the list of TUUIDs for a process.
219 The TRef kHasUUID bit is set and its fUniqueID is set to the fUniqueID
220 of the referenced object.
221 
222 When the TRef is streamed to a buffer, the corresponding TUUID is also
223 streamed with the TRef. When a TRef is read from a buffer, the corresponding
224 TUUID is also read and entered into the global list of TUUIDs (if not
225 already there). The TRef fUniqueID is set to the UUIDNumber.
226 see TProcessUUID for more details.
227 
228 ## Array of TRef
229 
230 The special class TRefArray should be used to store multiple references.
231 A TRefArray has one single pointer fPID for all objects in the array.
232 It has a dynamic compact table of fUniqueIDs. Use a TRefArray rather
233 then a collection of TRefs if all TRefs stem from the same process.
234 
235 Example:
236 
237 Suppose a TObjArray *mytracks containing a list of Track objects
238 Suppose a TRefArray *pions containing pointers to the pion tracks in mytracks.
239 This list is created with statements like: pions->Add(track);
240 Suppose a TRefArray *muons containing pointers to the muon tracks in mytracks.
241 The 3 arrays mytracks,pions and muons may be written separately.
242 */
243 
244 #include "TRef.h"
245 #include "TROOT.h"
246 #include "TClass.h"
247 #include "TProcessUUID.h"
248 #include "TRefTable.h"
249 #include "TObjArray.h"
250 #include "TExec.h"
251 #include "TSystem.h"
252 #include "TObjString.h"
253 
256 
257 ClassImp(TRef);
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// Create a ref to obj.
261 
263 {
264  *this = obj;
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// TRef copy ctor.
269 
270 TRef::TRef(const TRef &ref) : TObject(ref)
271 {
272  *this = ref;
273 }
274 
275 ////////////////////////////////////////////////////////////////////////////////
276 /// Assign object to reference.
277 
279 {
280  UInt_t uid = 0;
281  fPID = 0;
282  if (obj) {
283  if (obj->IsA()->CanIgnoreTObjectStreamer()) {
284  Error("operator= ","Class: %s IgnoreTObjectStreamer. Cannot reference object",obj->ClassName());
285  return;
286  }
287  if (obj->TestBit(kHasUUID)) {
288  fPID = gROOT->GetUUIDs();
289  obj->SetBit(kIsReferenced);
290  SetBit(kHasUUID);
291  uid = obj->GetUniqueID();
292  } else {
293  if (!obj->TestBit(kIsReferenced)) {
295  }
296  uid = obj->GetUniqueID();
299  }
300  }
301  SetUniqueID(uid);
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /// TRef assignment operator.
306 
308 {
309  if (this != &ref) {
310  SetUniqueID(ref.GetUniqueID());
311  fPID = ref.fPID;
313  }
314  return *this;
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Return kTRUE if r1 and r2 point to the same object.
319 
320 Bool_t operator==(const TRef &r1, const TRef &r2)
321 {
322  if (r1.GetPID() == r2.GetPID() && r1.GetUniqueID() == r2.GetUniqueID()) return kTRUE;
323  else return kFALSE;
324 }
325 
326 ////////////////////////////////////////////////////////////////////////////////
327 /// Return kTRUE if r1 and r2 do not point to the same object.
328 
329 Bool_t operator!=(const TRef &r1, const TRef &r2)
330 {
331  if (r1.GetPID() == r2.GetPID() && r1.GetUniqueID() == r2.GetUniqueID()) return kFALSE;
332  else return kTRUE;
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// If Exec with name does not exist in the list of Execs, it is created.
337 /// returns the index of the Exec in the list.
338 
340 {
341 #ifdef R__COMPLETE_MEM_TERMINATION
342  if (!fgExecs) GetListOfExecs();
343 #else
344  if (!fgExecs) fgExecs = new TObjArray(10);
345 #endif
346 
347  TExec *exec = (TExec*)fgExecs->FindObject(name);
348  if (!exec) {
349  // we register this Exec to the list of Execs.
350  exec = new TExec(name,"");
351  fgExecs->Add(exec);
352  }
353  return fgExecs->IndexOf(exec);
354 }
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 /// Return a pointer to the static TObjArray holding the list of Execs.
358 
360 {
361 #ifdef R__COMPLETE_MEM_TERMINATION
362  static TObjArray listOfExecs(10);
363  if (!fgExecs) {
364  listOfExecs.SetOwner(kTRUE);
365  fgExecs = &listOfExecs;
366  }
367 #else
368  if (!fgExecs) fgExecs = new TObjArray(10);
369 #endif
370  return fgExecs;
371 
372 }
373 
374 ////////////////////////////////////////////////////////////////////////////////
375 /// Return a pointer to the referenced object.
376 
378 {
379  //TObject *obj = 0;
380  if (!fPID) return 0;
381  if (!TProcessID::IsValid(fPID)) return 0;
382  UInt_t uid = GetUniqueID();
383 
384  //the reference may be in the TRefTable
386  if (table) {
387  table->SetUID(uid, fPID);
388  table->Notify();
389  }
390 
391  //Try to find the object from the table of the corresponding PID
392  TObject *obj = fPID->GetObjectWithID(uid);
393 
394  //if object not found, then exec action if an action has been defined
395  if (!obj) {
396  //execid in the first 8 bits
397  Int_t execid = TestBits(0xff0000);
398  if (execid > 0) {
399  execid = execid>>16;
400  TExec *exec = (TExec*)fgExecs->At(execid-1);
401  if (exec) {
402  //we expect the object to be returned via TRef::SetStaticObject
403  fgObject = const_cast<TRef*>(this);
404  exec->Exec();
405  if ((const TRef*)fgObject != this)
406  obj = fgObject;
407  else obj=0;
408  if (obj){
409  uid = TProcessID::AssignID(obj);
410  ((TRef*)this)->SetUniqueID(uid);
411  fPID->PutObjectWithID(obj,uid);
412  } else {
413  //well may be the Exec has loaded the object
414  obj = fPID->GetObjectWithID(uid);
415  }
416  }
417  }
418  }
419 
420  return obj;
421 }
422 
423 ////////////////////////////////////////////////////////////////////////////////
424 /// Store the exec number (in the ROOT list of Execs)
425 /// into the fBits of this TRef.
426 
427 void TRef::SetAction(const char *name)
428 {
429  TExec *exec = (TExec*)GetListOfExecs()->FindObject(name);
430  if (!exec) {
431  Error("SetAction","Unknown TExec: %s",name);
432  return;
433  }
434  Int_t execid = 1 + fgExecs->IndexOf(exec);
435  SetBit(execid << 16);
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 /// Find the action to be executed in the dictionary of the parent class
440 /// and store the corresponding exec number into fBits.
441 /// This function searches a data member in the class of parent with an
442 /// offset corresponding to this.
443 /// If a comment "TEXEC:" is found in the comment field of the data member,
444 /// the function stores the exec identifier of the exec statement
445 /// following this keyword.
446 
448 {
449  if (!parent) return;
450  if (gDirectory) gDirectory->SetTRefAction(this,parent);
451 }
452 
453  ///////////////////////////////////////////////////////////////////////////////
454  /// Returns the static object.
455 
457  return fgObject;
458 }
459 
460 ////////////////////////////////////////////////////////////////////////////////
461 /// static Obsolete function kept for back compatibility.
462 /// In the near future will print a Warning, then will be deleted.
463 
465 {
466  SetStaticObject(obj);
467 }
468 
469 ////////////////////////////////////////////////////////////////////////////////
470 /// Static function to set the object found on the Action on Demand function.
471 /// This function may be called by the user in the function called
472 /// when a "EXEC:" keyword is specified in the data member field of the TRef.
473 /// The function can get access to the dereferencing TRef (i.e. this)using
474 /// the static function GetStaticObject().
475 
477 {
478  fgObject = obj;
479 }
480 
481 ////////////////////////////////////////////////////////////////////////////////
482 /// Stream an object of class TRef.
483 
484 void TRef::Streamer(TBuffer &R__b)
485 {
486  UShort_t pidf;
487  if (R__b.IsReading()) {
488  TObject::Streamer(R__b);
489  if (TestBit(kHasUUID)) {
490  TString s;
491  s.Streamer(R__b);
492  TProcessUUID *pid = gROOT->GetUUIDs();
493  UInt_t number = pid->AddUUID(s.Data());
494  fPID = pid;
495  SetUniqueID(number);
496  if (gDebug > 1) {
497  printf("Reading TRef (HasUUID) uid=%d, obj=%lx\n",GetUniqueID(),(Long_t)GetObject());
498  }
499  } else {
500  R__b >> pidf;
501  pidf += R__b.GetPidOffset();
502  fPID = R__b.ReadProcessID(pidf);
503  //The execid has been saved in the unique id of the TStreamerElement
504  //being read by TStreamerElement::Streamer
505  //The current element (fgElement) is set as a static global
506  //by TStreamerInfo::ReadBuffer (Clones) when reading this TRef
507  Int_t execid = R__b.GetTRefExecId();
508  if (execid) SetBit(execid<<16);
509  if (gDebug > 1) {
510  printf("Reading TRef, pidf=%d, fPID=%lx, uid=%d, obj=%lx\n",pidf,(Long_t)fPID,GetUniqueID(),(Long_t)GetObject());
511  }
512  }
513  } else {
514  TObject::Streamer(R__b);
515 
516  if (TestBit(kHasUUID)) {
517  TObjString *objs = gROOT->GetUUIDs()->FindUUID(GetUniqueID());
518  objs->String().Streamer(R__b);
519  if (gDebug > 1) {
520  printf("Writing TRef (HasUUID) uid=%d, obj=%lx\n",GetUniqueID(),(Long_t)GetObject());
521  }
522  } else {
523  pidf = R__b.WriteProcessID(fPID);
524  R__b << pidf;
525  if (gDebug > 1) {
526  printf("Writing TRef, pidf=%d, fPID=%lx, uid=%d, obj=%lx\n",pidf,(Long_t)fPID,GetUniqueID(),(Long_t)GetObject());
527  }
528  }
529  }
530 }
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:375
Bool_t IsReading() const
Definition: TBuffer.h:83
void PutObjectWithID(TObject *obj, UInt_t uid=0)
stores the object at the uid th slot in the table of objects The object uniqued is set as well as its...
Definition: TProcessID.cxx:344
An array of TObjects.
Definition: TObjArray.h:37
This class is a specialized TProcessID managing the list of UUIDs.
Definition: TProcessUUID.h:32
Collectable string class.
Definition: TObjString.h:28
unsigned short UShort_t
Definition: RtypesCore.h:36
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
static void SetStaticObject(TObject *obj)
Static function to set the object found on the Action on Demand function.
Definition: TRef.cxx:476
#define gROOT
Definition: TROOT.h:402
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Int_t TestBits(UInt_t f) const
Definition: TObject.h:173
Basic string class.
Definition: TString.h:125
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual UShort_t GetPidOffset() const =0
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
static void SetObject(TObject *obj)
static Obsolete function kept for back compatibility.
Definition: TRef.cxx:464
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
Persistent Reference link to a TObject A TRef is a lightweight object pointing to any TObject...
Definition: TRef.h:32
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
static TObject * GetStaticObject()
Returns the static object.
Definition: TRef.cxx:456
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition: TBuffer.cxx:323
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
TProcessID * fPID
Definition: TRef.h:35
static TObject * fgObject
Definition: TRef.h:38
static Int_t AddExec(const char *name)
If Exec with name does not exist in the list of Execs, it is created.
Definition: TRef.cxx:339
virtual UShort_t WriteProcessID(TProcessID *pid)=0
Always return 0 (current processID).
Definition: TBuffer.cxx:332
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
static TObjArray * GetListOfExecs()
Return a pointer to the static TObjArray holding the list of Execs.
Definition: TRef.cxx:359
static TObjArray * fgExecs
Pointer to ProcessID when TRef was written.
Definition: TRef.h:37
static TProcessID * GetProcessWithUID(const TObject *obj)
static function returning a pointer to TProcessID with its pid encoded in the highest byte of obj->Ge...
Definition: TProcessID.cxx:267
TObject * GetObject() const
Return a pointer to the referenced object.
Definition: TRef.cxx:377
if object has a TUUID (its fUniqueID=UUIDNumber)
Definition: TObject.h:62
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual UInt_t GetTRefExecId()=0
friend Bool_t operator==(const TRef &r1, const TRef &r2)
Return kTRUE if r1 and r2 point to the same object.
Definition: TRef.cxx:320
TString & String()
Definition: TObjString.h:49
const Bool_t kFALSE
Definition: RtypesCore.h:88
void operator=(TObject *obj)
Assign object to reference.
Definition: TRef.cxx:278
TObject * GetObjectWithID(UInt_t uid)
returns the TObject with unique identifier uid in the table of objects
Definition: TProcessID.cxx:302
friend Bool_t operator!=(const TRef &r1, const TRef &r2)
Return kTRUE if r1 and r2 do not point to the same object.
Definition: TRef.cxx:329
long Long_t
Definition: RtypesCore.h:50
#define ClassImp(name)
Definition: Rtypes.h:359
static TRefTable * GetRefTable()
Static function returning the current TRefTable.
Definition: TRefTable.cxx:287
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:589
A TRefTable maintains the association between a referenced object and the parent object supporting th...
Definition: TRefTable.h:35
UInt_t AddUUID(TUUID &uuid, TObject *obj)
Add uuid to the table of UUIDs The TObject *obj has its uniqueID set to the UUID number return entry ...
static constexpr double s
TProcessID * GetPID() const
Definition: TRef.h:50
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void SetAction(const char *name)
Store the exec number (in the ROOT list of Execs) into the fBits of this TRef.
Definition: TRef.cxx:427
static UInt_t AssignID(TObject *obj)
static function returning the ID assigned to obj If the object is not yet referenced, its kIsReferenced bit is set and its fUniqueID set to the current number of referenced objects so far.
Definition: TProcessID.cxx:139
if object is referenced by a TRef or TRefArray
Definition: TObject.h:61
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
void Add(TObject *obj)
Definition: TObjArray.h:73
#define gDirectory
Definition: TDirectory.h:213
TRef()
Definition: TRef.h:42
void ResetBit(UInt_t f)
Definition: TObject.h:171
TExec is a utility class that can be used to execute a C++ command when some event happens in a pad...
Definition: TExec.h:28
static Bool_t IsValid(TProcessID *pid)
static function. return kTRUE if pid is a valid TProcessID
Definition: TProcessID.cxx:330
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual void SetUID(UInt_t uid, TProcessID *context=0)
Definition: TRefTable.h:87
char name[80]
Definition: TGX11.cxx:109
virtual void Exec(const char *command="")
Execute the command referenced by this object.
Definition: TExec.cxx:143
virtual Bool_t Notify()
This function is called by TRef::Streamer or TStreamerInfo::ReadBuffer when reading a reference...
Definition: TRefTable.cxx:299
const char * Data() const
Definition: TString.h:345