From 6370605015544b4330be0328eb435ea0a3206a26 Mon Sep 17 00:00:00 2001 From: wootguy Date: Tue, 23 Apr 2024 09:16:07 -0700 Subject: [PATCH] handle @include FGD method (fixes #12) also keep classes in alphabetical order within the groups --- src/editor/Fgd.cpp | 34 ++++++++++++++++++++++++++++++++++ src/editor/Fgd.h | 2 ++ src/editor/Renderer.cpp | 6 ++++++ src/globals.cpp | 1 + src/globals.h | 4 ++++ 5 files changed, 47 insertions(+) diff --git a/src/editor/Fgd.cpp b/src/editor/Fgd.cpp index 9e16a89b..ca4ce620 100644 --- a/src/editor/Fgd.cpp +++ b/src/editor/Fgd.cpp @@ -2,6 +2,8 @@ #include "util.h" #include #include +#include "globals.h" +#include map fgdKeyTypes{ {"integer", FGD_KEY_INTEGER}, @@ -49,6 +51,8 @@ void Fgd::merge(Fgd* other) { classes.push_back(newClass); classMap[className] = newClass; } + + sortClasses(); } bool Fgd::parse() { @@ -82,6 +86,24 @@ bool Fgd::parse() { if (line.empty()) continue; + if (line.find("@include") == 0) { + string baseFgd = getValueInQuotes(line.substr(8)); + string basePath = path.substr(0, path.find_last_of("/\\") + 1) + baseFgd; + + if (g_parsed_fgds.count(basePath)) { + continue; + } + g_parsed_fgds.insert(basePath); + + Fgd* tmp = new Fgd(basePath); + if (tmp->parse()) { + merge(tmp); + } + + delete tmp; + continue; + } + if (line[0] == '@') { if (bracketNestLevel) { logf("ERROR: New FGD class definition starts before previous one ends (line %d)\n", lineNum); @@ -122,6 +144,7 @@ bool Fgd::parse() { processClassInheritance(); createEntGroups(); setSpawnflagNames(); + sortClasses(); return true; } @@ -558,3 +581,14 @@ vector Fgd::splitStringIgnoringQuotes(string s, string delimitter) { return split; } + +bool sortFgdClasses(FgdClass* a, FgdClass* b) { return a->name < b->name; } + +void Fgd::sortClasses() { + for (int i = 0; i < solidEntGroups.size(); i++) { + std::sort(solidEntGroups[i].classes.begin(), solidEntGroups[i].classes.end(), sortFgdClasses); + } + for (int i = 0; i < pointEntGroups.size(); i++) { + std::sort(pointEntGroups[i].classes.begin(), pointEntGroups[i].classes.end(), sortFgdClasses); + } +} \ No newline at end of file diff --git a/src/editor/Fgd.h b/src/editor/Fgd.h index 505df4d0..9f881245 100644 --- a/src/editor/Fgd.h +++ b/src/editor/Fgd.h @@ -139,4 +139,6 @@ class Fgd { string getValueInQuotes(string s); vector splitStringIgnoringQuotes(string s, string delimitter); + + void sortClasses(); }; \ No newline at end of file diff --git a/src/editor/Renderer.cpp b/src/editor/Renderer.cpp index 8721497a..6cb5539d 100644 --- a/src/editor/Renderer.cpp +++ b/src/editor/Renderer.cpp @@ -605,7 +605,13 @@ void Renderer::loadSettings() { void Renderer::loadFgds() { Fgd* mergedFgd = NULL; + for (int i = 0; i < g_settings.fgdPaths.size(); i++) { + string path = g_settings.fgdPaths[i]; + + g_parsed_fgds.clear(); + g_parsed_fgds.insert(path); + Fgd* tmp = new Fgd(g_settings.fgdPaths[i]); if (!tmp->parse()) { diff --git a/src/globals.cpp b/src/globals.cpp index ea7d826d..39958fdb 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -12,6 +12,7 @@ AppSettings g_settings; string g_config_dir = getConfigDir(); string g_settings_path = g_config_dir + "bspguy.cfg"; Renderer* g_app = NULL; +std::set g_parsed_fgds; MapLimits g_limits; MapLimits g_engine_limits[ENGINE_TYPES]; \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index 4a155f55..1b6b7d36 100644 --- a/src/globals.h +++ b/src/globals.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "AppSettings.h" enum engine_types { @@ -51,4 +52,7 @@ extern MapLimits g_engine_limits[ENGINE_TYPES]; extern std::string g_config_dir; extern std::string g_settings_path; +// prevents infinite include loops +extern std::set g_parsed_fgds; + extern int g_render_flags; \ No newline at end of file