blob: 1956a899e8bdae57bb4fac0c0ae48be1c5a9e8dc (
plain)
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
|
#include "nodedumper.h"
#include <string>
#include <map>
#include <list>
#include "visitor.h"
#include "state.h"
#include "nodecache.h"
#include <sstream>
#include <iostream>
// For compatibility with old dump() output
#define NODEDUMPER_COMPAT_MODE
#ifdef NODEDUMPER_COMPAT_MODE
#include "dxflinextrudenode.h"
#include "dxfrotextrudenode.h"
#include "projectionnode.h"
#endif
bool NodeDumper::isCached(const AbstractNode &node)
{
return !this->cache[node].empty();
}
void NodeDumper::handleIndent(const State &state)
{
if (state.isPrefix()) {
this->currindent += "\t";
}
else if (state.isPostfix()) {
this->currindent.erase((this->currindent.length() >= 1) ?
this->currindent.length() - 1 : 0);
}
}
string NodeDumper::dumpChildren(const AbstractNode &node)
{
std::stringstream dump;
if (!this->visitedchildren[node.index()].empty()) {
dump << " {\n";
for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin();
iter != this->visitedchildren[node.index()].end();
iter++) {
dump << this->cache[**iter] << "\n";
}
dump << this->currindent << "}";
}
else {
#ifndef NODEDUMPER_COMPAT_MODE
dump << ";";
#else
if (dynamic_cast<const AbstractPolyNode*>(&node) &&
!dynamic_cast<const ProjectionNode*>(&node) &&
!dynamic_cast<const DxfRotateExtrudeNode*>(&node) &&
!dynamic_cast<const DxfLinearExtrudeNode*>(&node)) dump << ";";
else dump << " {\n" << this->currindent << "}";
#endif
}
return dump.str();
}
Response NodeDumper::visit(const State &state, const AbstractNode &node)
{
if (isCached(node)) return PruneTraversal;
else handleIndent(state);
if (state.isPostfix()) {
std::stringstream dump;
dump << this->currindent << node;
dump << dumpChildren(node);
this->cache.insert(node, dump.str());
}
handleVisitedChildren(state, node);
return ContinueTraversal;
}
const string &NodeDumper::getDump() const
{
assert(this->root);
return this->cache[*this->root];
}
void NodeDumper::handleVisitedChildren(const State &state, const AbstractNode &node)
{
if (state.isPostfix()) {
this->visitedchildren.erase(node.index());
if (!state.parent()) {
this->root = &node;
}
else {
this->visitedchildren[state.parent()->index()].push_back(&node);
}
}
}
|