summaryrefslogtreecommitdiff
path: root/src/nodedumper.cc
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);
		}
	}
}
contact: Jan Huwald // Impressum