blob: 1e77c9ebaa49cfa8752b41b1c2737e3d85cd0a0e (
plain) (
blame)
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
<#include "godot_scene.h"
#include <absl/strings/str_split.h>
#include <absl/strings/string_view.h>
#include <fstream>
#include <sstream>
#include <variant>
namespace com::fourisland::lingo2_archipelago {
namespace {
struct Heading {
std::string type;
std::string id;
std::string path;
std::string resource_type;
std::string name;
std::string parent;
GodotInstanceType instance_type;
};
Heading ParseTscnHeading(absl::string_view line) {
std::string original_line(line);
Heading heading;
if (line[0] != '[') {
std::ostringstream errormsg;
errormsg << "Heading must start with [." << std::endl
<< "Bad heading: " << original_line;
throw std::invalid_argument(errormsg.str());
}
line.remove_prefix(1);
int divider = line.find_first_of(" ]");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
heading.type = std::string(line.substr(0, divider));
line.remove_prefix(divider + 1);
while (!line.empty()) {
divider = line.find_first_of("=");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
std::string key(line.substr(0, divider));
line.remove_prefix(divider + 1);
if (line[0] == '"') {
line.remove_prefix(1);
divider = line.find_first_of("\"");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
std::string strval(line.substr(0, divider));
line.remove_prefix(divider + 2);
if (key == "name") {
heading.name = strval;
} else if (key == "parent") {
heading.parent = strval;
} else if (key == "path") {
heading.path = strval;
} else if (key == "type") {
heading.resource_type = strval;
} else if (key == "id") {
heading.id = strval;
}
} else if (line[0] == 'S' || line[0] == 'E') {
GodotInstanceType rrval;
char internal = line[0];
line.remove_prefix(13); // SubResource("
divider = line.find_first_of("\"");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
std::string refid = std::string(line.substr(0, divider));
line.remove_prefix(divider + 3);
GodotInstanceType instance_type;
if (internal == 'E') {
instance_type = GodotExtResourceRef{.id = refid};
} else {
// SubResource is not supported right now.
}
if (key == "instance") {
heading.instance_type = instance_type;
} else {
// Other keys aren't supported right now.
}
} else {
divider = line.find_first_of(" ]");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
int numval = std::atoi(line.substr(0, divider).data());
line.remove_prefix(divider + 1);
// keyvals_[key] = numval;
}
}
return heading;
}
} // namespace
std::string GodotNode::GetPath() const {
if (parent.empty() || parent == ".") {
return name;
} else {
return parent + "/" + name;
}
}
GodotScene ReadGodotSceneFromFile(const std::string& path) {
std::map<std::string, GodotExtResource> ext_resources;
std::vector<GodotNode> nodes;
std::ifstream input(path);
std::string line;
bool section_started = false;
Heading cur_heading;
std::ostringstream cur_value;
bool value_started = false;
auto handle_end_of_section = [&]() {
section_started = false;
value_started = false;
if (cur_heading.type == "sub_resource") {
// sub_resources_[std::get<int>(cur_heading.GetKeyval("id"))] =
// {cur_heading, cur_value.str(), ""};
} else {
// other_.emplace_back(cur_heading, cur_value.str());
}
cur_value = {};
};
while (std::getline(input, line)) {
if (section_started && (line.empty() || line[0] == '[')) {
handle_end_of_section();
}
if (!line.empty() && line[0] == '[') {
Heading heading = ParseTscnHeading(line);
if (heading.type == "gd_scene") {
// file_descriptor_ = heading;
} else if (heading.type == "ext_resource") {
GodotExtResource ext_resource;
ext_resource.path = heading.path;
ext_resource.type = heading.resource_type;
ext_resources[heading.id] = ext_resource;
} else if (heading.type == "node") {
if (heading.parent != "") {
nodes.push_back(GodotNode{.name = heading.name,
.parent = heading.parent,
.instance_type = heading.instance_type});
}
} else {
cur_heading = heading;
section_started = true;
}
} else if (!line.empty()) {
if (value_started) {
cur_value << std::endl;
} else {
value_started = true;
}
cur_value << line;
}
}
if (section_started) {
handle_end_of_section();
}
return GodotScene(std::move(ext_resources), std::move(nodes));
}
} // namespace com::fourisland::lingo2_archipelago
|