From 4e206fae5be6093b36c7779ba2a4a3679f0e754b Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Thu, 23 Nov 2023 01:47:18 +0000 Subject: something --- scene.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 scene.cpp (limited to 'scene.cpp') diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000..6eae537 --- /dev/null +++ b/scene.cpp @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heading.h" +#include "scene.h" + +Scene::Scene(const std::filesystem::path& path) { + std::ifstream input(path.c_str()); + 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(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(line); + if (heading.type() == "gd_scene") { + file_descriptor_ = heading; + } else if (heading.type() == "ext_resource") { + ext_resources_[std::get(heading.GetKeyval("id"))] = heading; + } 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(); + } + + for (const auto& [id, stuff] : sub_resources_) { + if (id >= next_sub_id_) { + next_sub_id_ = id + 1; + } + } +} + +int Scene::AddSubResource(const Script& script) { + int new_id = next_sub_id_++; + + std::ostringstream resource_contents; + for (const auto& [variable, value] : script.exports()) { + resource_contents << variable << " = SubResource( " << value << " )" + << std::endl; + } + resource_contents << "script/source = " << std::quoted(script.ToString()); + + Heading heading; + heading.set_type("sub_resource"); + heading.SetKeyval("type", "GDScript"); + heading.SetKeyval("id", new_id); + + sub_resources_[new_id] = {heading, resource_contents.str()}; + + return new_id; +} + +void Scene::RemoveExtResource(int id) { ext_resources_.erase(id); } + +void Scene::ReplaceScriptReferences(int ext_id, int sub_id) { + auto replace_refs = [&](std::string& text) { + std::ostringstream search_str; + search_str << "ExtResource( " << ext_id << " )"; + std::string search = search_str.str(); + + std::ostringstream new_text; + std::string_view corpus = text; + int location; + while ((location = corpus.find(search)) != std::string_view::npos) { + new_text << corpus.substr(0, location) << "SubResource( " << sub_id + << " )"; + corpus.remove_prefix(location + search.size()); + } + new_text << corpus; + + text = new_text.str(); + }; + + for (auto& [id, stuff] : sub_resources_) { + auto& [heading, text] = stuff; + replace_refs(text); + } + + for (auto& [heading, text] : other_) { + replace_refs(text); + } +} + +std::string Scene::ToString() const { + std::ostringstream output; + output << file_descriptor_.ToString() << std::endl; + + for (const auto& [id, heading] : ext_resources_) { + output << heading.ToString(); + } + + output << std::endl; + + for (const auto& [id, resource] : sub_resources_) { + const auto& [heading, value] = resource; + output << heading.ToString() << value << std::endl << std::endl; + } + + for (const auto& [heading, value] : other_) { + output << heading.ToString() << value << std::endl << std::endl; + } + + return output.str(); +} -- cgit 1.4.1