From f74b4ec5d432025f541bd95cb31ba67b07a2f46c Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Sun, 17 Nov 2024 03:22:01 +0200 Subject: [PATCH] S-Expression: Minimize lag when parsing level names `sexp::Parser` now supports specifying a custom `depth` property for omitting (not parsing) structures deeper than `depth` in the tree, starting from 0. This optimizes parsing level names from level files a ton, since level files tend to be very big and used to take a while to parse collectively. --- external/sexp-cpp | 2 +- src/supertux/level_parser.cpp | 2 +- src/util/reader_document.cpp | 15 +++++++++++---- src/util/reader_document.hpp | 5 +++-- src/util/reader_mapping.cpp | 6 +----- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/external/sexp-cpp b/external/sexp-cpp index 6018831abc1..ece5200d1e7 160000 --- a/external/sexp-cpp +++ b/external/sexp-cpp @@ -1 +1 @@ -Subproject commit 6018831abc1e5d5020c7b62f99962806dacf4c9f +Subproject commit ece5200d1e79c72c927143ebef87ce05cd1ff32d diff --git a/src/supertux/level_parser.cpp b/src/supertux/level_parser.cpp index 63584112e5f..ead6ca2caae 100644 --- a/src/supertux/level_parser.cpp +++ b/src/supertux/level_parser.cpp @@ -34,7 +34,7 @@ LevelParser::get_level_name(const std::string& filename) try { register_translation_directory(filename); - auto doc = ReaderDocument::from_file(filename); + auto doc = ReaderDocument::from_file(filename, 1); auto root = doc.get_root(); if (root.get_name() != "supertux-level") { diff --git a/src/util/reader_document.cpp b/src/util/reader_document.cpp index 41a00eefb03..455f2373e5a 100644 --- a/src/util/reader_document.cpp +++ b/src/util/reader_document.cpp @@ -24,14 +24,21 @@ #include "util/log.hpp" ReaderDocument -ReaderDocument::from_stream(std::istream& stream, const std::string& filename) +ReaderDocument::from_string(const std::string& string, const std::string& filename, int depth) { - sexp::Value sx = sexp::Parser::from_stream(stream, sexp::Parser::USE_ARRAYS); + std::istringstream stream(string); + return from_stream(stream, filename, depth); +} + +ReaderDocument +ReaderDocument::from_stream(std::istream& stream, const std::string& filename, int depth) +{ + sexp::Value sx = sexp::Parser::from_stream(stream, sexp::Parser::USE_ARRAYS, depth); return ReaderDocument(filename, std::move(sx)); } ReaderDocument -ReaderDocument::from_file(const std::string& filename) +ReaderDocument::from_file(const std::string& filename, int depth) { log_debug << "ReaderDocument::parse: " << filename << std::endl; @@ -41,7 +48,7 @@ ReaderDocument::from_file(const std::string& filename) msg << "Parser problem: Couldn't open file '" << filename << "'."; throw std::runtime_error(msg.str()); } else { - return from_stream(in, filename); + return from_stream(in, filename, depth); } } diff --git a/src/util/reader_document.hpp b/src/util/reader_document.hpp index 8438dda5841..097b838a276 100644 --- a/src/util/reader_document.hpp +++ b/src/util/reader_document.hpp @@ -27,8 +27,9 @@ class ReaderDocument final { public: - static ReaderDocument from_stream(std::istream& stream, const std::string& filename = ""); - static ReaderDocument from_file(const std::string& filename); + static ReaderDocument from_string(const std::string& string, const std::string& filename = "", int depth = -1); + static ReaderDocument from_stream(std::istream& stream, const std::string& filename = "", int depth = -1); + static ReaderDocument from_file(const std::string& filename, int depth = -1); public: ReaderDocument(const std::string& filename, sexp::Value sx); diff --git a/src/util/reader_mapping.cpp b/src/util/reader_mapping.cpp index a7bcef0200e..c4f681fa202 100644 --- a/src/util/reader_mapping.cpp +++ b/src/util/reader_mapping.cpp @@ -129,11 +129,7 @@ ReaderMapping::get(const char* key, std::string& value, const std::optional