File: DataNode.h

package info (click to toggle)
endless-sky 0.10.16-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 414,608 kB
  • sloc: cpp: 73,435; python: 893; xml: 666; sh: 271; makefile: 28
file content (99 lines) | stat: -rw-r--r-- 4,150 bytes parent folder | download
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
/* DataNode.h
Copyright (c) 2014 by Michael Zahniser

Endless Sky is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.

Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include <cstdint>
#include <list>
#include <string>
#include <vector>



// A DataNode is a single line of a DataFile. It consists of one or more tokens,
// which can be interpreted either as strings or as floating point values, and
// it may also have "children," which may each in turn have their own children.
// The tokens of a node are separated by white space, with quotation marks being
// used to group multiple words into a single token. If the token text contains
// quotation marks, it should be enclosed in backticks instead.
class DataNode {
public:
	// Construct a DataNode. For the purpose of printing stack traces, each node
	// must remember what its parent node is.
	explicit DataNode(const DataNode *parent = nullptr) noexcept(false);
	// Copying or moving a DataNode requires updating the parent pointers.
	DataNode(const DataNode &other);
	DataNode &operator=(const DataNode &other);
	DataNode(DataNode &&) noexcept;
	DataNode &operator=(DataNode &&) noexcept;

	// Get the number of tokens in this node.
	int Size() const noexcept;
	// Get all the tokens in this node as an iterable vector.
	const std::vector<std::string> &Tokens() const noexcept;
	// Add tokens to the node.
	void AddToken(const std::string &token);
	// Get the token at the given index. No bounds checking is done internally.
	// DataFile loading guarantees index 0 always exists.
	const std::string &Token(int index) const;
	// Convert the token at the given index to a number. This returns 0 and prints an
	// error if the index is out of range or the token cannot be interpreted as a number.
	double Value(int index) const;
	static double Value(const std::string &token);
	// Check if the token at the given index is a number in a format that this
	// class is able to parse.
	bool IsNumber(int index) const;
	static bool IsNumber(const std::string &token);
	// Convert the token at the given index to a boolean. This returns false
	// and prints an error if the index is out of range or the token cannot
	// be interpreted as a number.
	bool BoolValue(int index) const;
	// Check if the token at the given index is a boolean, i.e. "true"/"1" or "false"/"0"
	// as a string.
	bool IsBool(int index) const;
	static bool IsBool(const std::string &token);
	// Check if the token can be used as name for a condition.
	static bool IsConditionName(const std::string &token);

	// Add a new child. The child's parent must be this node.
	void AddChild(const DataNode &child);
	// Check if this node has any children. If so, the iterator functions below
	// can be used to access them.
	bool HasChildren() const noexcept;
	std::list<DataNode>::const_iterator begin() const noexcept;
	std::list<DataNode>::const_iterator end() const noexcept;

	// Print a message followed by a "trace" of this node and its parents.
	int PrintTrace(const std::string &message = "") const;


private:
	// Adjust the parent pointers when a copy is made of a DataNode.
	void Reparent() noexcept;


private:
	// These are "child" nodes found on subsequent lines with deeper indentation.
	std::list<DataNode> children;
	// These are the tokens found in this particular line of the data file.
	std::vector<std::string> tokens;
	// The parent pointer is used only for printing stack traces.
	const DataNode *parent = nullptr;
	// The line number in the given file that produced this node.
	size_t lineNumber = 0;

	// Allow DataFile to modify the internal structure of DataNodes.
	friend class DataFile;
};