Logo ROOT   6.14/05
Reference Guide
TMessageHandler.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Rene Brun 11/11/99
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 TMessageHandler
13 
14 \ingroup Base
15 Handle messages that might be generated by the system.
16 By default a handler only keeps track of the different messages
17 generated for a specific class. By deriving from this class and
18 overriding Notify() one can implement custom message handling.
19 In Notify() one has access to the message id and the object
20 generating the message. One can install more than one message
21 handler per class. A message handler can be removed or again
22 added when needed.
23 
24  - All Root "Warnings" are logged as message 1001
25  - All Root "Errors" are logged as message 1002
26  - All Root "SysErrors" are logged as message 1003
27  - All Root "Fatals" are logged as message 1004
28 */
29 
30 #include "TMessageHandler.h"
31 #include "TClass.h"
32 #include "TROOT.h"
33 #include "TVirtualMutex.h"
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Create a new message handler for class cl and add it to the list
39 /// of message handlers.
40 
42 {
43  fClass = cl;
44  fMessObj = 0;
45  fMessId = 0;
46  fSize = 0;
47  fCnts = 0;
48  fMessIds = 0;
49  fDerived = derived;
50 
51  if (fClass)
53  else
54  SetName("DefaultMessageHandler");
55 
56  Add();
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Create a new message handler for class named cl and add it to the list
61 /// of message handlers.
62 
63 TMessageHandler::TMessageHandler(const char *cl, Bool_t derived)
64 {
66  fMessObj = 0;
67  fMessId = 0;
68  fSize = 0;
69  fCnts = 0;
70  fMessIds = 0;
71  fDerived = derived;
72 
73  SetName(cl);
74 
76  Add();
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Clean up the message handler.
81 
83 {
84  Remove();
85  if (fSize <= 0) return;
86  delete [] fCnts;
87  delete [] fMessIds;
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Add this message handler to the list of messages handlers.
92 
94 {
96  gROOT->GetListOfMessageHandlers()->Add(this);
97  if (fClass) {
98  // don't emit signal when the default message handler is added
99  // as this happens in the TROOT ctor and the TQObject stuff is
100  // not yet properly initialized on some platforms
101  Added(); // emit Added() signal
102  }
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Return counter for message with ID=messid.
107 
109 {
110  if (fSize <= 0) return 0;
111  for (Int_t i = 0; i < fSize; i++) {
112  if (fMessIds[i] == messId) return fCnts[i];
113  }
114  return 0;
115 }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Return total number of messages.
119 
121 {
122  if (fSize <= 0) return 0;
123  Int_t count = 0;
124  for (Int_t i = 0; i < fSize; i++) {
125  count += fCnts[i];
126  }
127  return count;
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// Store message origin, keep statistics and call Notify().
132 
134 {
135  // check if message must be managed by this message handler
136  if (fClass) {
137  if (fDerived) {
138  if(!obj->InheritsFrom(fClass)) return;
139  } else {
140  if (obj->IsA() != fClass) return;
141  }
142  }
143 
144  fMessId = id;
145  fMessObj = obj;
146 
147  Notify();
148 
149  // increment statistics
150  Int_t i;
151  // first message
152  if (fSize <= 0) {
153  fSize = 1;
154  fCnts = new Int_t[fSize];
155  fMessIds = new Int_t[fSize];
156  } else {
157  // already existing message
158  for (i = 0; i < fSize; i++) {
159  if (fMessIds[i] == fMessId) {
160  fCnts[i]++;
161  return;
162  }
163  }
164  // new message
165  fSize++;
166  Int_t *newCnts = new Int_t[fSize];
167  Int_t *newMessIds = new Int_t[fSize];
168  for (i = 0; i < fSize-1; i++) {
169  newCnts[i] = fCnts[i];
170  newMessIds[i] = fMessIds[i];
171  }
172  delete [] fCnts;
173  delete [] fMessIds;
174  fCnts = newCnts;
175  fMessIds = newMessIds;
176  }
177  fCnts[fSize-1] = 1;
178  fMessIds[fSize-1] = fMessId;
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// This method must be overridden to handle object notification.
183 
185 {
186  if (fClass) return kFALSE;
187  // case of default handler
188  // encode class number in message id
189  if (!fMessObj) return kFALSE;
190  Int_t uid = Int_t(fMessObj->IsA()->GetUniqueID());
191  fMessId += 10000*uid;
192  fMessId = -fMessId;
193  Notified(); // emit Notified() signal
194  return kFALSE;
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Print statistics for this message handler.
199 
201 {
202  printf("\n ****** Message Handler: %s has a total of %d messages\n",GetName(),GetTotalMessageCount());
203  if (fSize <= 0) return;
204  Int_t id, uid;
205  const TClass *cl;
206  TIter next(gROOT->GetListOfClasses());
207  for (Int_t i = 0; i < fSize; i++) {
208  id = fMessIds[i];
209  cl = fClass;
210  if (id < 0) {
211  id = -id;
212  uid = id/10000;
213  id = id%10000;
214  next.Reset();
215  while ((cl = (TClass*)next())) {
216  if (cl->GetUniqueID() == UInt_t(uid)) break;
217  }
218  }
219  if (!cl) cl = gROOT->IsA();
220  if (id == 1001) {
221  printf(" Class: %-20s WARNINGs has %d counts\n",cl->GetName(),fCnts[i]);
222  continue;
223  }
224  if (id == 1002) {
225  printf(" Class: %-20s ERRORs has %d counts\n",cl->GetName(),fCnts[i]);
226  continue;
227  }
228  printf(" Class: %-20s MessID = %5d has %d counts\n",cl->GetName(),id,fCnts[i]);
229  }
230 }
231 
232 ////////////////////////////////////////////////////////////////////////////////
233 /// Remove this message handler from the list of messages handlers.
234 
236 {
238  gROOT->GetListOfMessageHandlers()->Remove(this);
239  Removed(); // emit Removed() signal
240 }
virtual Int_t GetMessageCount(Int_t messId) const
Return counter for message with ID=messid.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:375
Handle messages that might be generated by the system.
const char Option_t
Definition: RtypesCore.h:62
virtual void Removed()
virtual void Add()
Add this message handler to the list of messages handlers.
virtual void HandleMessage(Int_t id, const TObject *obj)
Store message origin, keep statistics and call Notify().
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
#define gROOT
Definition: TROOT.h:410
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
XFontStruct * id
Definition: TGX11.cxx:108
virtual Bool_t Notify()
This method must be overridden to handle object notification.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
unsigned int UInt_t
Definition: RtypesCore.h:42
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual void Notified()
virtual ~TMessageHandler()
Clean up the message handler.
virtual void Added()
#define ClassImp(name)
Definition: Rtypes.h:359
virtual void Print(Option_t *option="") const
Print statistics for this message handler.
#define R__LOCKGUARD(mutex)
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:2887
virtual void Remove()
Remove this message handler from the list of messages handlers.
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t GetTotalMessageCount() const
Return total number of messages.
TMessageHandler(const TClass *cl, Bool_t derived=kTRUE)
Create a new message handler for class cl and add it to the list of message handlers.
const TObject * fMessObj
const TClass * fClass