From a9635dbf7480d00fd9ef40cf1c606e623fe4c540 Mon Sep 17 00:00:00 2001 From: Garux Date: Sun, 3 Aug 2025 18:20:19 +0500 Subject: [PATCH] fix fgd @include (only load once) --- radiant/eclass_fgd.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/radiant/eclass_fgd.cpp b/radiant/eclass_fgd.cpp index 4d59ef30..f02bc6d8 100644 --- a/radiant/eclass_fgd.cpp +++ b/radiant/eclass_fgd.cpp @@ -544,9 +544,9 @@ void EntityClassFGD_parseClass( Tokeniser& tokeniser, bool fixedsize, bool isBas } } -void EntityClassFGD_loadFile( const char* filename ); +using LoadInclude = std::function; -void EntityClassFGD_parse( TextInputStream& inputStream, const char* path ){ +void EntityClassFGD_parse( TextInputStream& inputStream, const char* path, const LoadInclude& loadInclude ){ Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser( inputStream ); tokeniser.nextLine(); @@ -573,7 +573,7 @@ void EntityClassFGD_parse( TextInputStream& inputStream, const char* path ){ } // hl2 below else if ( string_equal( blockType, "@include" ) ) { - EntityClassFGD_loadFile( StringStream( PathFilenameless( path ), tokeniser.getToken() ) ); + loadInclude( tokeniser.getToken() ); } else if ( string_equal( blockType, "@mapsize" ) ) { ASSERT_MESSAGE( EntityClassFGD_parseToken( tokeniser, "(" ), PARSE_ERROR ); @@ -594,12 +594,12 @@ void EntityClassFGD_parse( TextInputStream& inputStream, const char* path ){ } -void EntityClassFGD_loadFile( const char* filename ){ +void EntityClassFGD_loadFile( const char* filename, const LoadInclude& loadInclude ){ TextFileInputStream file( filename ); if ( !file.failed() ) { globalOutputStream() << "parsing entity classes from " << makeQuoted( filename ) << '\n'; - EntityClassFGD_parse( file, filename ); + EntityClassFGD_parse( file, filename, loadInclude ); } } @@ -701,8 +701,14 @@ public: constructDirectory( gameDirectory, "fgd" ); } - for( const auto& [ name, path ] : name_path ){ - EntityClassFGD_loadFile( StringStream( path, name ) ); + const LoadInclude loadInclude = [&]( const char *name ){ + if( auto it = name_path.find( name ); it != name_path.end() && it->second != nullptr ) // null path == loaded + EntityClassFGD_loadFile( StringStream( std::exchange( it->second, nullptr ), name ), loadInclude ); + }; + + for( auto& [ name, path ] : name_path ){ + if( path != nullptr ) // null path == loaded + EntityClassFGD_loadFile( StringStream( std::exchange( path, nullptr ), name ), loadInclude ); } }