-
Notifications
You must be signed in to change notification settings - Fork 1
/
cobjectgraph.cc
165 lines (146 loc) · 3.91 KB
/
cobjectgraph.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <cstdlib>
#include <sstream>
#include <stdexcept>
#include "cobjectgraph.h"
using namespace std;
using namespace CObjectGraph;
int BaseNode::counter = 1;
BaseNode::BaseNode()
{
ostringstream oss;
oss << "node" << BaseNode::counter++;
this->name = oss.str();
}
string BaseNode::GetName() const
{
return this->name;
}
Edge::Edge(const BaseNode * from, const BaseNode * to, string label)
{
this->from = from;
this->to = to;
this->label = label;
}
string Edge::ToDot()
{
ostringstream oss;
oss << this->from->GetName();
oss << " -> " << this->to->GetName();
oss << " [label=\"" << this->label << "\"]";
return oss.str();
}
BaseNode * Graph::FindNodeForObject(const void * object)
{
for (const auto& node : nodes)
if (node->RepresentsObject(object))
return node.get();
return nullptr;
}
void Graph::AddEdge(const BaseNode * from, const BaseNode * to, string label)
{
if (from == nullptr)
{
throw runtime_error("from cannot be null");
}
if (to == nullptr)
{
throw runtime_error("to cannot be null");
}
Edge * e = new Edge(from , to, label);
edges.push_back(unique_ptr<Edge>(e));
}
void Graph::AddEdge(const void * fromObject, const void * toObject, string label)
{
const BaseNode * from = FindNodeForObject(fromObject);
const BaseNode * to = FindNodeForObject(toObject);
if (from == nullptr)
{
throw runtime_error("Could not find the node for fromObject");
}
if (to == nullptr)
{
throw runtime_error("Could not find the node for toObject");
}
AddEdge(from, to, label);
}
void Graph::SetSameRank(const BaseNode * obj1Node, const BaseNode * obj2Node)
{
vector< const BaseNode * > s;
if (obj1Node == nullptr)
{
throw runtime_error("obj1Node cannot be null");
}
if (obj2Node == nullptr)
{
throw runtime_error("obj2Node cannot be null");
}
s.push_back(obj1Node);
s.push_back(obj2Node);
rankings.push_back(s);
}
void Graph::SetSameRank(const void* obj1, const void* obj2)
{
BaseNode * obj1Node = FindNodeForObject(obj1);
BaseNode * obj2Node = FindNodeForObject(obj2);
if (obj1Node == nullptr)
{
throw runtime_error("Could not find the node for obj1");
}
if (obj2Node == nullptr)
{
throw runtime_error("Could not find the node for obj2");
}
SetSameRank(obj1Node, obj2Node);
}
void Graph::SetAttribute(AttributeScope scope, std::string key, std::string value)
{
if (scope == AttributeScope::SPECIFIC_NODE)
throw logic_error("Cannot set a node-specific attribute on Graph!");
set_attribute(attributes, key, value, scope);
}
void Graph::PrintDot(std::ostream& os)
{
os << "digraph " << title << " {\n";
// Print attributes
for (const auto& a : attributes)
{
switch (a.scope)
{
case AttributeScope::GRAPH:
os << " " << a.key << " = " << "\"" << a.value << "\";\n";
break;
case AttributeScope::ALL_NODES:
os << " node [ " << a.key << " = " << "\"" << a.value << "\" ]\n";
break;
case AttributeScope::ALL_EDGES:
os << " edge [ " << a.key << " = " << "\"" << a.value << "\" ]\n";
break;
case AttributeScope::SPECIFIC_NODE:
throw runtime_error("Node-specific attibute in Graph!");
}
}
os << "\n";
// Print nodes
for (const auto& n : nodes)
{
os << " " << n->ToDot() << "\n";
}
os << "\n";
// Print rankings
for (const auto& r : rankings)
{
os << " { rank=same; ";
for (const auto& n : r)
{
os << n->GetName() << " ";
}
os << " }\n";
}
os << "\n";
// Print edges
for (const auto& e : edges)
{
os << " " << e->ToDot() << "\n";
}
os << "}\n";
}