Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TStructViewer.cxx
Go to the documentation of this file.
1// @(#)root/gviz3d:$Id$
2// Author: Tomasz Sosnicki 18/09/09
3
4/************************************************************************
5* Copyright (C) 1995-2009, 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 "TStructViewer.h"
13#include "TStructNodeProperty.h"
14#include "TStructViewerGUI.h"
15#include "TStructNode.h"
16
17#include <TDataMember.h>
19#include <TClassEdit.h>
20#include <vector>
21
22
23class TA {
24public:
25 virtual ~TA() {}
26};
27
28//________________________________________________________________________
29//////////////////////////////////////////////////////////////////////////
30//
31// TStructViewer viewer represents class, struct or other type as an object in 3D space.
32// At the top of the scene we can see objects which is our pointer. Under it we see
33// pointers and collection elements. Collection must inherit from TCollection
34// or be STL collecion.
35//
36// We can change the number of visible levels or objects on the scene with the GUI or
37// methods. The size of geometry objects is proportional to the memory taken by this object
38// or to the number of members inside this object.
39//
40// An easy way to find some class in the viewer is to change the color of the type.
41// We can connect for example a TF2 class with red color or connect all classes
42// inheriting from TF2 by adding plus to name. For example typename "TF2+" tells us
43// that all classes inheriting from TF2 will be red.
44//
45// Navigation in viewer is very simple like in usual GLViewer. When you put the mouse over
46// some object you can see some information about it (e.g. name, size, actual level).
47// When you double click this object, it becames top object on scene.
48// Undo and redo operation are supported.
49//
50// Begin_Html
51// <p> In this picture we can see TStructViewer with pointer to TList which contains
52// other collections and objects of various classes</p>
53// <img src="gif/TStructViewer1.jpg">
54// End_Html
55//
56// Begin_Html
57// <p> Other screenshot presents opened TStructNodeEditor</p>
58// <img src="gif/TStructViewer2.jpg">
59// End_Html
60//
61//
62//////////////////////////////////////////////////////////////////////////
63
64
65////////////////////////////////////////////////////////////////////////////////
66/// Default constructor. An argument "ptr" is a main pointer of type "clname", which should be shown in the viewer
67
68TStructViewer::TStructViewer(void* ptr, const char * clname)
69{
70 fPointer = nullptr;
71 fPointerClass = nullptr;
72 fTopNode = nullptr;
73
74 // add default color
75 fColors.Add(new TStructNodeProperty("+", 17));
76
77 // creating GUI
78 fGUI = new TStructViewerGUI(this, nullptr, &fColors);
79
80 SetPointer(ptr, clname);
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// Destructor. Clean all object after closing the viewer
85
92
93////////////////////////////////////////////////////////////////////////////////
94/// Find list with nodes on specified level and add node to this list and increment list of sizes and list of members
95
97{
98 TList* list = (TList*)fLevelArray[node->GetLevel()];
99 // if list doesn't exist -> create one
100 if(!list) {
101 fLevelArray[node->GetLevel()] = list = new TList();
102 }
103 list->Add(node);
104
105 // increase number of members on this level
106 fLevelMembersCount(node->GetLevel())++;
107 // increase size of this level
108 fLevelSize(node->GetLevel()) += size;
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Count allocated memory, increase member counters, find child nodes
113
114void TStructViewer::CountMembers(TClass* cl, TStructNode* parent, void* pointer)
115{
116 if(!cl) {
117 return;
118 }
119
120 if (cl->InheritsFrom(TClass::Class())) {
121 return;
122 }
123
124 //////////////////////////////////////////////////////////////////////////
125 // DATA MEMBERS
126 //////////////////////////////////////////////////////////////////////////
127 // Set up list of RealData so TClass doesn't create a new object itself
128 cl->BuildRealData(parent->GetPointer());
129 TIter it(cl->GetListOfDataMembers());
130 TDataMember* dm;
131 while ((dm = (TDataMember*) it() ))
132 {
133 // increase counters in parent node
134 parent->SetAllMembersCount(parent->GetAllMembersCount() + 1);
135 parent->SetMembersCount(parent->GetMembersCount() + 1);
136
137 if (dm->Property() & kIsStatic) {
138 continue;
139 }
140
141
142 void* ptr = nullptr;
143
144 if(dm->IsaPointer()) {
146
147 // skip if pointer to pointer
148 if(trueTypeName.EndsWith("**")) {
149 continue;
150 }
151
152 if (!pointer) {
153 continue;
154 }
155
156 void** pptr = (void**)((ULongptr_t)pointer + dm->GetOffset());
157 ptr = *pptr;
158
159 if (!ptr) {
160 continue;
161 }
162
163 if(fPointers.GetValue((ULongptr_t)ptr)) {
164 continue;
165 } else {
167 }
168
169 ULong_t size = 0;
170 if (TClass* cl2 = TClass::GetClass(dm->GetTypeName())) {
171 size = cl2->Size();
172 }
173
174 if(size == 0) {
175 size = dm->GetUnitSize();
176 }
177
179 if(dm->GetDataType()) { // pointer to basic type
180 type = kBasic;
181 } else {
182 type = kClass;
183 }
184
185 // creating TStructNode
186 TStructNode* node = new TStructNode(dm->GetName(), dm->GetTypeName(), ptr, parent, size, type);
187 AddNode(node, size);
188
189 CountMembers(TClass::GetClass(dm->GetTypeName()), node, ptr);
190
191 // total size = size of parent + size of nodes daughters
192 parent->SetTotalSize(parent->GetTotalSize() + node->GetTotalSize() - size);
193 // all members of node = all nodes of parent + nodes of daughter - 1 because node is added twice
194 parent->SetAllMembersCount(parent->GetAllMembersCount() + node->GetAllMembersCount() - 1);
195 } else {
196 ptr = (void*)((ULongptr_t)pointer + dm->GetOffset());
197
198 if (!ptr) {
199 continue;
200 }
201 CountMembers(TClass::GetClass(dm->GetTypeName()), parent, ptr);
202 }
203
204 //////////////////////////////////////////////////////////////////////////
205 // STL COLLECTION
206 //////////////////////////////////////////////////////////////////////////
207 if (dm->IsSTLContainer()) {
209
210 //it works only for pointer in std object (not pointer)
212 if (!stlClass) {
213 continue;
214 }
215
216 TVirtualCollectionProxy* proxy = stlClass->GetCollectionProxy();
217 if (!proxy) {
218 continue;
219 }
221
222 UInt_t count = proxy->Size();
223 parent->SetMembersCount(parent->GetMembersCount() + count);
224
225 if (!proxy->HasPointers() || proxy->GetType() != kNoType_t) { // only objects or pointers to basic type
226 parent->SetTotalSize(parent->GetTotalSize() + count * proxy->Sizeof());
227 parent->SetAllMembersCount(parent->GetAllMembersCount() + count);
228 } else {
229 TClass* clProxy = proxy->GetValueClass();
231 TString typeName;
232 // get size of element
233 ULong_t size = 0;
234 if (clProxy) {
235 name = clProxy->GetName();
236 typeName = clProxy->GetName();
237 size = clProxy->Size();
238 } else {
239 continue;
240 }
241
242 // if there is no dictionary
243 if (size == 0) {
244 size = proxy->Sizeof();
245 }
246
247 // searching pointer to pointer
248 Bool_t ptp = kFALSE;
249 std::vector<std::string> parts;
250 int loc;
252 std::vector<std::string>::const_iterator iPart = parts.begin();
253 while (iPart != parts.end() && (*iPart).empty())
254 ++iPart;
255 if (iPart != parts.end() && *iPart != dm->GetTypeName()) {
256 for (std::vector<std::string>::const_iterator iP = iPart,
257 iPE = parts.end(); iP != iPE; ++iP) {
258 if (TString(TClassEdit::ResolveTypedef(iP->c_str(), true).c_str()).EndsWith("**")){
259 ptp = kTRUE;
260 break;
261 }
262 }
263 }
264 if (ptp) {
265 continue;
266 }
267
268
269 void* element;
270 for (UInt_t i = 0; i < count ; i++) {
271 element = *(void**)proxy->At(i);
272
273 if (!element) {
274 continue;
275 }
276 if (clProxy->IsTObject()) {
277 name = ((TObject*) element)->GetName();
278 }
279
280 // create node
281 TStructNode* node = new TStructNode(name, typeName, element, parent, size, kClass);
282 // add addition information
283 AddNode(node, size);
284 // increase parents counter
285 parent->SetMembersCount(parent->GetMembersCount() + 1);
286
288 parent->SetTotalSize(parent->GetTotalSize() + node->GetTotalSize());
289 parent->SetAllMembersCount(parent->GetAllMembersCount() + node->GetAllMembersCount());
290 }
291 }
292 }
293 }
294
295 //////////////////////////////////////////////////////////////////////////
296 // COLLECTION
297 //////////////////////////////////////////////////////////////////////////
298 // if our parent node is collection
300 // we change type of node to collection
301 parent->SetNodeType(kCollection);
302
303 // return if invalid pointer to collection
304 if (!pointer) {
305 return;
306 }
307
308 TIter it2((TCollection*)pointer);
309 TObject* item;
310 // loop through all elements in collection
311 while((item = it2())) {
312 // get size of element
313 ULong_t size = 0;
314 if (TClass* cl3 = item->IsA()){
315 size = cl3->Size();
316 }
317
318 // if there is no dictionary
319 if (size == 0) {
320 size = sizeof(item);
321 }
322
323 // create node
324 TStructNode* node = new TStructNode(item->GetName(), item->ClassName(), item, parent, size, kClass);
325 // add addition information
326 AddNode(node, size);
327 // increase parents counter
328 parent->SetMembersCount(parent->GetMembersCount() + 1);
329
330 CountMembers(item->IsA(), node, item);
331
332 parent->SetTotalSize(parent->GetTotalSize() + node->GetTotalSize());
333 parent->SetAllMembersCount(parent->GetAllMembersCount() + node->GetAllMembersCount());
334 }
335 }
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Draw object if there is valid pointer
340
342{
343 TString opt(option);
344 if(opt == "count") {
345
346 } else if (opt == "size") {
347
348 }
349
350
351 if (fTopNode) {
353 } else {
354
355 }
356}
357
358////////////////////////////////////////////////////////////////////////////////
359/// Returns canvas used to keep TGeoVolumes
360
362{
363 return fGUI->GetCanvas();
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Returns pointer to main window
368
370{
371 return fGUI;
372}
373////////////////////////////////////////////////////////////////////////////////
374/// Return main pointer
375
377{
378 return fPointer;
379}
380
381////////////////////////////////////////////////////////////////////////////////
382/// Returns TExMap with pairs <level number, number of objects>
383
388
389////////////////////////////////////////////////////////////////////////////////
390/// Returns TExMap with pairs <level number, size of level in bytes>
391
393{
394 return fLevelSize;
395}
396
397////////////////////////////////////////////////////////////////////////////////
398/// Get visibility of links between objects
399
404
405////////////////////////////////////////////////////////////////////////////////
406/// Create top node and find all member nodes
407
409{
410 if (fTopNode) {
411 Reset();
412 }
413
415
416 TString name = "Main pointer";
417 if (fPointerClass->IsTObject()) {
418 name = ((TObject*) fPointer)->GetName();
419 }
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Deleting nodes, maps and array
427
429{
430 TList* lst;
431 TIter it(&fLevelArray);
432 while ((lst = (TList*) it() )) {
433 lst->SetOwner();
434 lst->Clear();
435 }
436
437 // deleting maps and array
442
443 fTopNode = nullptr;
444}
445
446////////////////////////////////////////////////////////////////////////////////
447/// Sets color for the class "name" to color "color"
448
450{
451 TIter it(&fColors);
453 while ((prop = (TStructNodeProperty*) it() )) {
454 if (name == prop->GetName()) {
455 prop->SetColor(TColor::GetColor(color));
456 fGUI->Update();
457
458 return;
459 }
460 }
461
462 // add color
463 prop = new TStructNodeProperty(name.Data(), color);
465 fColors.Sort();
466}
467
468////////////////////////////////////////////////////////////////////////////////
469/// ISets links visibility
470
475
476////////////////////////////////////////////////////////////////////////////////
477/// Set main pointer of class "clname"
478
479void TStructViewer::SetPointer(void* ptr, const char* clname)
480{
481 if (ptr) {
482 TA* a = (TA*) ptr;
483 if (clname) {
485 } else {
486 fPointerClass = TClass::GetClass(typeid(*a));
487 }
488
489 if (!fPointerClass) {
490 return;
491 }
492
493 fPointer = ptr;
494 Prepare();
496 }
497}
498
499////////////////////////////////////////////////////////////////////////////////
500/// Returns color associated with type "typeName"
501
502TColor TStructViewer::GetColor(const char* typeName)
503{
504 TIter it(&fColors);
506 while((prop = (TStructNodeProperty*) it())) {
507 if (!strcmp(prop->GetName(), typeName)) {
508 return prop->GetColor();
509 }
510 }
511
512 return TColor();
513}
#define a(i)
Definition RSha256.hxx:99
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:69
unsigned long ULongptr_t
Unsigned integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:90
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kNoType_t
Definition TDataType.h:33
@ kIsStatic
Definition TDictionary.h:80
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h prop
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
ENodeType
Definition TStructNode.h:18
@ kSTLCollection
Definition TStructNode.h:23
@ kClass
Definition TStructNode.h:20
@ kCollection
Definition TStructNode.h:21
@ kBasic
Definition TStructNode.h:22
const_iterator begin() const
const_iterator end() const
virtual ~TA()
The Canvas class.
Definition TCanvas.h:23
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
static TClass * Class()
void BuildRealData(void *pointer=nullptr, Bool_t isTransient=kFALSE)
Build a full list of persistent data members.
Definition TClass.cxx:2036
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition TClass.cxx:3797
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5743
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition TClass.cxx:5980
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4901
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:2973
Collection abstract base class.
Definition TCollection.h:65
static TClass * Class()
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
The color creation and management class.
Definition TColor.h:22
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
const char * GetTrueTypeName() const
Get the desugared type name of this data member, including const and volatile qualifiers.
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
Int_t GetUnitSize() const
Get the sizeof the underlying type of the data member (i.e.
Int_t IsSTLContainer()
The return type is defined in TDictionary (kVector, kList, etc.)
Bool_t IsaPointer() const
Return true if data member is a pointer.
TDataType * GetDataType() const
Definition TDataMember.h:76
Longptr_t GetOffset() const
Get offset from "this".
const char * GetTypeName() const
Get the decayed type name of this data member, removing const and volatile qualifiers,...
This class stores a (key,value) pair using an external hash.
Definition TExMap.h:33
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition TExMap.cxx:87
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition TExMap.cxx:173
Defines top level windows that interact with the system Window Manager.
Definition TGFrame.h:399
A doubly linked list.
Definition TList.h:38
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:399
void Add(TObject *obj) override
Definition TList.h:81
virtual void Sort(Bool_t order=kSortAscending)
Sort linked list.
Definition TList.cxx:934
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
void Clear(Option_t *option="") override
Remove all objects from the array.
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Clear(Option_t *="")
Definition TObject.h:125
Basic string class.
Definition TString.h:138
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2250
void SetNodeType(ENodeType type)
Sets type of node to "type".
ULong_t GetAllMembersCount() const
Returns number of all members in node.
ULong_t GetMembersCount() const
Returns numbers of members of node.
void SetMembersCount(ULong_t count)
Sets number of members to "number".
void * GetPointer() const
Returns main pointer.
void SetTotalSize(ULong_t size)
Sets total size of allocated memory in bytes to value "size".
void SetAllMembersCount(ULong_t count)
Sets numbers of all members to "number".
UInt_t GetLevel() const
Returns actual level of node.
ULong_t GetTotalSize() const
Returns total size of allocated memory in bytes.
void SetNodePtr(TStructNode *val)
Sets top node pointer and updates view.
Bool_t GetLinksVisibility() const
Returns true if links are visible, otherwise return false.
void SetLinksVisibility(Bool_t val)
Sets links visibility to "visible".
void Update(Bool_t resetCamera=false)
Updates view. Clear all the nodes, call draw function and update scene. Doesn't reset camera.
TExMap fLevelMembersCount
TCanvas * GetCanvas()
Returns canvas used to keep TGeoVolumes.
TGMainFrame * GetFrame()
Returns pointer to main window.
void SetLinksVisibility(Bool_t val)
ISets links visibility.
TStructViewer(void *ptr=nullptr, const char *clname=nullptr)
Default constructor. An argument "ptr" is a main pointer of type "clname", which should be shown in t...
TObjArray fLevelArray
void CountMembers(TClass *cl, TStructNode *parent, void *pointer)
Count allocated memory, increase member counters, find child nodes.
void SetColor(TString name, Int_t color)
Sets color for the class "name" to color "color".
TColor GetColor(const char *typeName)
Returns color associated with type "typeName".
void Draw(Option_t *option="") override
Draw object if there is valid pointer.
void Reset()
Deleting nodes, maps and array.
TStructNode * fTopNode
~TStructViewer() override
Destructor. Clean all object after closing the viewer.
Bool_t GetLinksVisibility() const
Get visibility of links between objects.
void SetPointer(void *ptr, const char *clname=nullptr)
Set main pointer of class "clname".
void Prepare()
Create top node and find all member nodes.
void * GetPointer() const
Return main pointer.
TStructViewerGUI * fGUI
void AddNode(TStructNode *node, ULong_t size)
Find list with nodes on specified level and add node to this list and increment list of sizes and lis...
TClass * fPointerClass
TExMap GetLevelMembersCount() const
Returns TExMap with pairs <level number, number of objects>
TExMap GetLevelSize() const
Returns TExMap with pairs <level number, size of level in bytes>
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.