PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
VCG.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/base/VCG.cpp
4// Purpose: Class members that can produce data files
5// interpretable by VCG viewer.
6// Author: Shane T. Mueller, Ph.D.
7// Copyright: (c) 2003--2005 Shane T. Mueller <smueller@obereed.net>
8// License: GPL 2
9//
10//
11//
12//
13// This file is part of the PEBL project.
14//
15// PEBL is free software; you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation; either version 2 of the License, or
18// (at your option) any later version.
19//
20// PEBL is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23// GNU General Public License for more details.
24//
25// You should have received a copy of the GNU General Public License
26// along with PEBL; if not, write to the Free Software
27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
30#include "PNode.h"
31#include "VCG.h"
32#include "Variant.h"
33
34#include <list>
35#include <iostream>
36#include <stdlib.h>
37#include <stdio.h>
38#include <strstream>
39
40using std::cerr;
41using std::cout;
42using std::endl;
43using std::flush;
44using std::list;
45using std::ostream;
46
47
51 mNodeIndex((int)0),
52 mHeader(strdup("/*PEBL VGC-Tool Graph for selected program.\n (C) 2003 Shane T. Mueller, Ph.D.*/\n"))
53{
54 mGraph = new VCGGraph();
55}
56
60{
61 free(mHeader);
62 delete mGraph;
63}
64
65void VCG::MakeGraph(const PNode * node)
66{
67 //First, fill up the mGraph structure by parsing the graph
68 Evaluate(node, NULL, 1);
69}
70
72{
73 //First, put in some identifying information
74 cout << mHeader;
75 if(mGraph)
76 {
77 cout << (*mGraph) << endl;
78 }
79}
80
81
82void VCG::Evaluate(const PNode * node, const char* parent, const int anchor)
83{
84
85
86 //First, generate a unique name for the node
87 char * name;
88 ostrstream ost1;
89 ost1 << "NODE-" << mNodeIndex++;
90 ost1.put(0); //null terminate the ostring-stream
91 name = strdup(ost1.str());
92
93
94 //Now determine what type of node it is, and what
95 //value resides within it.
96
97 //Start making a label; use an ostrstream for easy concatenation
98
99 ostrstream ost2;
100 Variant variant;
101
102 switch(node->GetType())
103 {
104 case PEBL_OP_NODE:
105
106 ost2 << "OpNode\\n" << ((OpNode*)node)->GetOpName();
107 break;
108
109 case PEBL_DATA_NODE:
110
111 //retrieve tha vlaue from tha data node
112 variant = ((DataNode*)node)->GetValue();
113
114 ost2 << variant.GetDataTypeName() << "\\n" << variant;
115
116 break;
117
118 default:
119 ost2 << "Unknown Node Type\\nUnknown Value";
120
121 }
122
123 //Null-terminate the label stream and make it into a char array
124 ost2.put(0);
125 char* label = strdup(ost2.str());
126
127 //Now, create a new node with all the right trimmings.
128 cerr << "About to make node with: ["<< name << "] and [" << label << "]." << endl;
129
130 VCGNode * tmpNode=new VCGNode(name, label);
131
132 //Change the shape and color of the node if it is an OpNode
133 if(node->GetType() == PEBL_OP_NODE)
134 {
135 tmpNode->SetShape("ellipse");
136 tmpNode->SetBorderColor("red");
137 }
138 else if(node->GetType() == PEBL_DATA_NODE)
139 {
140 tmpNode->SetShape("box");
141 tmpNode->SetBorderColor("black");
142
143 }
144 else
145 {
146 tmpNode->SetShape("rhomb");
147 tmpNode->SetBorderColor("orange");
148
149 }
150
151
152 mGraph->AddNode(tmpNode);
153
154
155 //Now, add an edge from this node's parent to the current node
156 if(parent)
157 {
158 VCGEdge * tmpEdge = new VCGEdge(parent,name);
159 tmpEdge->SetAnchor(anchor);
160 mGraph->AddEdge(tmpEdge);
161 }
162
163 // Now, if we are an OpNode, evaluate each of the child nodes (if they exist)
164
165 if(node->GetType() == PEBL_OP_NODE)
166 {
167 PNode *left, *right;
168 left = ((OpNode*)node)->GetLeft();
169 right = ((OpNode*)node)->GetRight();
170
171 if(left) Evaluate(left, name, 1);
172 if(right) Evaluate(right, name, 2);
173 }
174
175 //Clean up after ourselves
176 free(name);
177 free(label);
178}
179
180
181
182
183
187 mTitle(strdup("VCG Graph File for PEBL-Interpreted PCode Tree")),
188 mSplines(true),
189 mWidth(700),
190 mHeight(700),
191 mX(30),
192 mY(30),
193 mColor(strdup("blue"))
194{
195
196
197}
198
199
203{
204 free(mTitle);
205 free(mColor);
206}
207
208
210{
211 mVCGEdges.push_front(*edge);
212}
213
215{
216
217 mVCGNodes.push_front(*node);
218
219}
220
221
222
223ostream & operator <<(ostream& out, VCGGraph & v)
224{
225
226 //Get Initial stuff:
227 out << "graph: { title: \"" << v.GetTitle() << "\"\n";
228 out << " splines: no\n";
229 out << " layoutalgorithm: tree\n";
230 out << " smanhattan_edges: yes\n";
231 out << " finetuning: yes\n";
232 out << " portsharing: no\n";
233 out << " treefactor: 0.2\n";
234 out << " width: " << v.GetWidth() << endl;
235 out << " height: " << v.GetHeight() << endl;
236 out << " x: " << v.GetX() << endl;
237 out << " y: " << v.GetY() << endl;
238 out << " color: " << v.GetColor() << endl;
239
240 //Now, output each Node;
241 v.OutputNodes(out);
242
243 //Now, output each edge;
244 v.OutputEdges(out);
245
246
247 //Cap off the end and return the entire stream
248 out << "\n}" << endl;
249 return out;
250}
251
252void VCGGraph::OutputNodes(ostream &out)
253{
254
255
256 list<VCGNode>::iterator p = mVCGNodes.begin();
257
258 //cerr << "/*Number of Nodes: " << mVCGNodes.size() << "*/"<< endl;
259 while(p != mVCGNodes.end())
260 {
261 out << *p << endl;
262 p++;
263 }
264 out << "\n";
265
266}
267
268void VCGGraph::OutputEdges(ostream & out)
269{
270
271 list<VCGEdge>::iterator p = mVCGEdges.begin();
272
273 // cout << "/*Number of Edges: " << mVCGEdges.size() << "*/" << endl;
274 while(p != mVCGEdges.end())
275 {
276 out << *p << endl;
277 p++;
278 }
279 out << "\n";
280
281}
282
283
284
285
289 mTitle(strdup("Default VCG Node Title")),
290 mLabel(strdup("Default Label")),
291 mShape(strdup("box")),
292 mBorderColor(strdup("black"))
293{
294 //Standard Constructor
295
296}
297
298
301VCGNode::VCGNode(const char * title, const char * label ):
302 mTitle(strdup(title)),
303 mLabel(strdup(label)),
304 mShape(strdup("box")),
305 mBorderColor(strdup("black"))
306
307{
308 //Standard Constructor
309
310}
311
312
313
317{
318 free(mTitle);
319 free(mLabel);
320 free(mShape);
321 free(mBorderColor);
322}
323
324
325ostream & operator <<(ostream& out, VCGNode & v )
326{
327
328 //Output the beginning of a node:
329 out << "node: { title: \"" << v.GetTitle() << "\"\n";
330 out << " label: \"" << v.GetLabel() << "\"\n";
331 out << " shape: " << v.GetShape() << "\n";
332 out << " bordercolor: " << v.GetBorderColor() << "\n";
333 out << " }\n";
334 return out;
335}
336
337
341 mThickness(2),
342 mFrom(0),
343 mTo(0),
344 mAnchor(1)
345{
346
347}
348
349
352VCGEdge::VCGEdge(const char* from, const char* to):
353 mThickness(2),
354 mFrom(strdup(from)),
355 mTo(strdup(to)),
356 mAnchor(1)
357{
358}
359
360
364{
365 free(mFrom);
366 free(mTo);
367
368}
369
370
371
372ostream& operator <<(ostream& out, VCGEdge & v )
373{
374 //Output the beginning of a node:
375 out << "edge: { sourcename: \"" << v.GetFrom() << "\"\n";
376 out << " targetname: \"" << v.GetTo() << "\"\n";
377 out << " thickness: " << v.GetThickness() << "\n";
378 // out << " anchor: " << v.GetAnchor() << "\n";
379 out << " }\n";
380 return out;
381}
382
#define NULL
Definition BinReloc.cpp:317
@ PEBL_OP_NODE
Definition PNode.h:35
@ PEBL_DATA_NODE
Definition PNode.h:36
ostream & operator<<(ostream &out, VCGGraph &v)
Definition VCG.cpp:223
Definition PNode.h:45
PNODE_TYPE GetType() const
Access mType data.
Definition PNode.h:61
Definition VCG.h:123
~VCGEdge()
Standard Destructor for the 'Edge' class.
Definition VCG.cpp:363
VCGEdge()
Standard Constructor for the 'Edge' class.
Definition VCG.cpp:340
char * GetTo() const
Definition VCG.h:137
char * GetFrom() const
Definition VCG.h:136
void SetAnchor(const int i)
Definition VCG.h:132
int GetThickness() const
Definition VCG.h:135
Definition VCG.h:62
int GetWidth() const
Definition VCG.h:73
void AddNode(VCGNode *node)
Definition VCG.cpp:214
void OutputNodes(std::ostream &out)
Definition VCG.cpp:252
char * GetColor() const
Definition VCG.h:77
void AddEdge(VCGEdge *edge)
Definition VCG.cpp:209
~VCGGraph()
Standard Destructor for the 'Graph' class.
Definition VCG.cpp:202
char * GetTitle() const
Definition VCG.h:72
int GetHeight() const
Definition VCG.h:74
void OutputEdges(std::ostream &out)
Definition VCG.cpp:268
VCGGraph()
Standard Constructor for the 'Graph' class.
Definition VCG.cpp:186
int GetY() const
Definition VCG.h:76
int GetX() const
Definition VCG.h:75
Definition VCG.h:98
char * GetLabel() const
Definition VCG.h:110
VCGNode()
Standard Constructor for the 'Graph' class.
Definition VCG.cpp:288
void SetBorderColor(const char *color)
Definition VCG.h:107
char * GetTitle() const
Definition VCG.h:109
void SetShape(const char *shape)
Definition VCG.h:106
char * GetShape() const
Definition VCG.h:111
char * GetBorderColor() const
Definition VCG.h:112
~VCGNode()
Standard Destructor for the 'Graph' class.
Definition VCG.cpp:316
~VCG()
Standard Destructor for Main VCG class.
Definition VCG.cpp:59
void PrintGraph()
Definition VCG.cpp:71
void Evaluate(const PNode *node, const char *parent, const int anchor)
Definition VCG.cpp:82
void MakeGraph(const PNode *node)
Definition VCG.cpp:65
VCG()
Standard Constructor for Main VCG class.
Definition VCG.cpp:50
std::string GetDataTypeName() const
This returns the type as a string.
Definition Variant.cpp:891