summary refs log tree commit diff stats
path: root/scene.cpp
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2023-11-23 01:47:18 +0000
committerStar Rauchenberger <fefferburbia@gmail.com>2023-11-23 01:47:18 +0000
commit4e206fae5be6093b36c7779ba2a4a3679f0e754b (patch)
tree3a1377ae7781debeb04c17464f9eab13f7e47131 /scene.cpp
downloadgodot3-tscn-compactor-4e206fae5be6093b36c7779ba2a4a3679f0e754b.tar.gz
godot3-tscn-compactor-4e206fae5be6093b36c7779ba2a4a3679f0e754b.tar.bz2
godot3-tscn-compactor-4e206fae5be6093b36c7779ba2a4a3679f0e754b.zip
something
Diffstat (limited to 'scene.cpp')
-rw-r--r--scene.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000..6eae537 --- /dev/null +++ b/scene.cpp
@@ -0,0 +1,139 @@
1#include <filesystem>
2#include <fstream>
3#include <iomanip>
4#include <iostream>
5#include <map>
6#include <sstream>
7#include <stdexcept>
8#include <string_view>
9#include <variant>
10
11#include "heading.h"
12#include "scene.h"
13
14Scene::Scene(const std::filesystem::path& path) {
15 std::ifstream input(path.c_str());
16 std::string line;
17 bool section_started = false;
18 Heading cur_heading;
19 std::ostringstream cur_value;
20 bool value_started = false;
21 auto handle_end_of_section = [&]() {
22 section_started = false;
23 value_started = false;
24
25 if (cur_heading.type() == "sub_resource") {
26 sub_resources_[std::get<int>(cur_heading.GetKeyval("id"))] = {
27 cur_heading, cur_value.str()};
28 } else {
29 other_.emplace_back(cur_heading, cur_value.str());
30 }
31
32 cur_value = {};
33 };
34 while (std::getline(input, line)) {
35 if (section_started && (line.empty() || line[0] == '[')) {
36 handle_end_of_section();
37 }
38 if (!line.empty() && line[0] == '[') {
39 Heading heading(line);
40 if (heading.type() == "gd_scene") {
41 file_descriptor_ = heading;
42 } else if (heading.type() == "ext_resource") {
43 ext_resources_[std::get<int>(heading.GetKeyval("id"))] = heading;
44 } else {
45 cur_heading = heading;
46 section_started = true;
47 }
48 } else if (!line.empty()) {
49 if (value_started) {
50 cur_value << std::endl;
51 } else {
52 value_started = true;
53 }
54 cur_value << line;
55 }
56 }
57 if (section_started) {
58 handle_end_of_section();
59 }
60
61 for (const auto& [id, stuff] : sub_resources_) {
62 if (id >= next_sub_id_) {
63 next_sub_id_ = id + 1;
64 }
65 }
66}
67
68int Scene::AddSubResource(const Script& script) {
69 int new_id = next_sub_id_++;
70
71 std::ostringstream resource_contents;
72 for (const auto& [variable, value] : script.exports()) {
73 resource_contents << variable << " = SubResource( " << value << " )"
74 << std::endl;
75 }
76 resource_contents << "script/source = " << std::quoted(script.ToString());
77
78 Heading heading;
79 heading.set_type("sub_resource");
80 heading.SetKeyval("type", "GDScript");
81 heading.SetKeyval("id", new_id);
82
83 sub_resources_[new_id] = {heading, resource_contents.str()};
84
85 return new_id;
86}
87
88void Scene::RemoveExtResource(int id) { ext_resources_.erase(id); }
89
90void Scene::ReplaceScriptReferences(int ext_id, int sub_id) {
91 auto replace_refs = [&](std::string& text) {
92 std::ostringstream search_str;
93 search_str << "ExtResource( " << ext_id << " )";
94 std::string search = search_str.str();
95
96 std::ostringstream new_text;
97 std::string_view corpus = text;
98 int location;
99 while ((location = corpus.find(search)) != std::string_view::npos) {
100 new_text << corpus.substr(0, location) << "SubResource( " << sub_id
101 << " )";
102 corpus.remove_prefix(location + search.size());
103 }
104 new_text << corpus;
105
106 text = new_text.str();
107 };
108
109 for (auto& [id, stuff] : sub_resources_) {
110 auto& [heading, text] = stuff;
111 replace_refs(text);
112 }
113
114 for (auto& [heading, text] : other_) {
115 replace_refs(text);
116 }
117}
118
119std::string Scene::ToString() const {
120 std::ostringstream output;
121 output << file_descriptor_.ToString() << std::endl;
122
123 for (const auto& [id, heading] : ext_resources_) {
124 output << heading.ToString();
125 }
126
127 output << std::endl;
128
129 for (const auto& [id, resource] : sub_resources_) {
130 const auto& [heading, value] = resource;
131 output << heading.ToString() << value << std::endl << std::endl;
132 }
133
134 for (const auto& [heading, value] : other_) {
135 output << heading.ToString() << value << std::endl << std::endl;
136 }
137
138 return output.str();
139}