* fix equally named builds execution

This commit is contained in:
Garux 2024-01-09 23:42:42 +06:00
parent 27dff0c888
commit 3212660e1f
4 changed files with 69 additions and 83 deletions

View File

@ -56,8 +56,8 @@ class Evaluatable
{ {
public: public:
virtual ~Evaluatable(){} virtual ~Evaluatable(){}
virtual void evaluate( StringBuffer& output ) = 0; virtual void evaluate( StringBuffer& output ) const = 0;
virtual void exportXML( XMLImporter& importer ) = 0; virtual void exportXML( XMLImporter& importer ) const = 0;
}; };
class VariableString : public Evaluatable class VariableString : public Evaluatable
@ -74,7 +74,7 @@ public:
void setString( const char* string ){ void setString( const char* string ){
m_string = string; m_string = string;
} }
void evaluate( StringBuffer& output ){ void evaluate( StringBuffer& output ) const override {
StringBuffer variable; StringBuffer variable;
bool in_variable = false; bool in_variable = false;
for ( const char* i = m_string.c_str(); *i != '\0'; ++i ) for ( const char* i = m_string.c_str(); *i != '\0'; ++i )
@ -106,7 +106,7 @@ public:
} }
} }
} }
void exportXML( XMLImporter& importer ){ void exportXML( XMLImporter& importer ) const override {
importer << c_str(); importer << c_str();
} }
}; };
@ -122,14 +122,14 @@ public:
delete m_test; delete m_test;
delete m_result; delete m_result;
} }
void evaluate( StringBuffer& output ){ void evaluate( StringBuffer& output ) const override {
StringBuffer buffer; StringBuffer buffer;
m_test->evaluate( buffer ); m_test->evaluate( buffer );
if ( !string_empty( buffer.c_str() ) ) { if ( !string_empty( buffer.c_str() ) ) {
m_result->evaluate( output ); m_result->evaluate( output );
} }
} }
void exportXML( XMLImporter& importer ){ void exportXML( XMLImporter& importer ) const override {
StaticElement conditionElement( "cond" ); StaticElement conditionElement( "cond" );
conditionElement.insertAttribute( "value", m_test->c_str() ); conditionElement.insertAttribute( "value", m_test->c_str() );
importer.pushElement( conditionElement ); importer.pushElement( conditionElement );
@ -145,24 +145,24 @@ class Tool : public Evaluatable
Evaluatables m_evaluatables; Evaluatables m_evaluatables;
public: public:
~Tool(){ ~Tool(){
for ( Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i ) for ( auto* e : m_evaluatables )
{ {
delete ( *i ); delete ( e );
} }
} }
void push_back( Evaluatable* evaluatable ){ void push_back( Evaluatable* evaluatable ){
m_evaluatables.push_back( evaluatable ); m_evaluatables.push_back( evaluatable );
} }
void evaluate( StringBuffer& output ){ void evaluate( StringBuffer& output ) const override {
for ( Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i ) for ( const auto* e : m_evaluatables )
{ {
( *i )->evaluate( output ); e->evaluate( output );
} }
} }
void exportXML( XMLImporter& importer ){ void exportXML( XMLImporter& importer ) const override {
for ( Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i ) for ( const auto* e : m_evaluatables )
{ {
( *i )->exportXML( importer ); e->exportXML( importer );
} }
} }
}; };
@ -312,34 +312,22 @@ inline bool is_separator( const CopiedString& name, const Build& commands ){
} }
return true; return true;
} }
inline bool is_separator( const BuildPair &p ){
return is_separator( p.first, p.second );
}
typedef std::list<BuildPair> Project; typedef std::list<BuildPair> Project;
Project::iterator Project_find( Project& project, const char* name ){
return std::find_if( project.begin(), project.end(), [name]( const BuildPair& self ){ return string_equal( self.first.c_str(), name ); } );
}
Project::iterator Project_find( Project& project, std::size_t index ){ Project::iterator Project_find( Project& project, std::size_t index ){
return index < project.size() return index < project.size()
? std::next( project.begin(), index ) ? std::next( project.begin(), index )
: project.end(); : project.end();
} }
// returns either found index or fallback to 0
Build& project_find( Project& project, const char* build ){ size_t Project_find( const Project& project, const Project::const_iterator iterator ){
Project::iterator i = Project_find( project, build ); size_t idx = 0;
ASSERT_MESSAGE( i != project.end(), "error finding build command" ); for( auto i = project.cbegin(); i != project.cend(); ++i, ++idx )
return ( *i ).second;
}
bool Project_contains( const Project& project, Project::const_iterator iterator ){
for( auto i = project.cbegin(); i != project.cend(); ++i )
if( i == iterator ) if( i == iterator )
return true; return idx;
return false; return 0;
} }
Build::iterator Build_find( Build& build, std::size_t index ){ Build::iterator Build_find( Build& build, std::size_t index ){
@ -480,32 +468,29 @@ void project_verify( Project& project, Tools& tools ){
#endif #endif
} }
void build_run( const char* name, CommandListener& listener ){ void build_run( size_t buildIdx, CommandListener& listener ){
for ( Tools::iterator i = g_build_tools.begin(); i != g_build_tools.end(); ++i ) for ( const auto& [ name, tool ] : g_build_tools )
{ {
StringBuffer output; StringBuffer output;
( *i ).second.evaluate( output ); tool.evaluate( output );
build_set_variable( ( *i ).first.c_str(), output.c_str() ); build_set_variable( name.c_str(), output.c_str() );
} }
if ( const auto buildIt = Project_find( g_build_project, buildIdx ); buildIt != g_build_project.end() )
{ {
Project::iterator i = Project_find( g_build_project, name ); g_lastExecutedBuild = buildIt;
if ( i != g_build_project.end() ) { for ( const auto& command : buildIt->second )
g_lastExecutedBuild = i;
Build& build = ( *i ).second;
for ( Build::iterator j = build.begin(); j != build.end(); ++j )
{
StringBuffer output;
( *j ).evaluate( output );
if ( !output.empty() )
listener.execute( output.c_str() );
}
}
else
{ {
globalErrorStream() << "build " << makeQuoted( name ) << " not defined"; StringBuffer output;
command.evaluate( output );
if ( !output.empty() )
listener.execute( output.c_str() );
} }
} }
else
{
globalErrorStream() << "build #" << buildIdx << " not defined";
}
} }
@ -561,17 +546,17 @@ void build_commands_clear(){
class BuildXMLExporter class BuildXMLExporter
{ {
Build& m_build; const Build& m_build;
public: public:
BuildXMLExporter( Build& build ) : m_build( build ){ BuildXMLExporter( const Build& build ) : m_build( build ){
} }
void exportXML( XMLImporter& importer ){ void exportXML( XMLImporter& importer ) const {
importer << "\n"; importer << "\n";
for ( Build::iterator i = m_build.begin(); i != m_build.end(); ++i ) for ( const auto& command : m_build )
{ {
StaticElement commandElement( "command" ); StaticElement commandElement( "command" );
importer.pushElement( commandElement ); importer.pushElement( commandElement );
( *i ).exportXML( importer ); command.exportXML( importer );
importer.popElement( commandElement.name() ); importer.popElement( commandElement.name() );
importer << "\n"; importer << "\n";
} }
@ -580,29 +565,29 @@ public:
class ProjectXMLExporter class ProjectXMLExporter
{ {
Project& m_project; const Project& m_project;
Tools& m_tools; const Tools& m_tools;
public: public:
ProjectXMLExporter( Project& project, Tools& tools ) : m_project( project ), m_tools( tools ){ ProjectXMLExporter( const Project& project, const Tools& tools ) : m_project( project ), m_tools( tools ){
} }
void exportXML( XMLImporter& importer ){ void exportXML( XMLImporter& importer ) const {
StaticElement projectElement( "project" ); StaticElement projectElement( "project" );
projectElement.insertAttribute( "version", BUILDMENU_VERSION ); projectElement.insertAttribute( "version", BUILDMENU_VERSION );
importer.pushElement( projectElement ); importer.pushElement( projectElement );
importer << "\n"; importer << "\n";
for ( Tools::iterator i = m_tools.begin(); i != m_tools.end(); ++i ) for ( const auto& [ name, tool ] : m_tools )
{ {
StaticElement toolElement( "var" ); StaticElement toolElement( "var" );
toolElement.insertAttribute( "name", ( *i ).first.c_str() ); toolElement.insertAttribute( "name", name.c_str() );
importer.pushElement( toolElement ); importer.pushElement( toolElement );
( *i ).second.exportXML( importer ); tool.exportXML( importer );
importer.popElement( toolElement.name() ); importer.popElement( toolElement.name() );
importer << "\n"; importer << "\n";
} }
for ( Project::iterator i = m_project.begin(); i != m_project.end(); ++i ) for ( const auto& [ name, build ] : m_project )
{ {
if ( is_separator( *i ) ) { if ( is_separator( name, build ) ) {
StaticElement buildElement( "separator" ); StaticElement buildElement( "separator" );
importer.pushElement( buildElement ); importer.pushElement( buildElement );
importer.popElement( buildElement.name() ); importer.popElement( buildElement.name() );
@ -611,9 +596,9 @@ public:
else else
{ {
StaticElement buildElement( "build" ); StaticElement buildElement( "build" );
buildElement.insertAttribute( "name", ( *i ).first.c_str() ); buildElement.insertAttribute( "name", name.c_str() );
importer.pushElement( buildElement ); importer.pushElement( buildElement );
BuildXMLExporter buildExporter( ( *i ).second ); BuildXMLExporter buildExporter( build );
buildExporter.exportXML( importer ); buildExporter.exportXML( importer );
importer.popElement( buildElement.name() ); importer.popElement( buildElement.name() );
importer << "\n"; importer << "\n";
@ -954,9 +939,7 @@ void LoadBuildMenu();
void DoBuildMenu(){ void DoBuildMenu(){
ProjectList projectList( g_build_project ); ProjectList projectList( g_build_project );
const Project bakproj = g_build_project; const Project bakproj = g_build_project;
const size_t baklast = Project_contains( g_build_project, g_lastExecutedBuild ) const size_t baklast = Project_find( g_build_project, g_lastExecutedBuild );
? std::distance( g_build_project.cbegin(), g_lastExecutedBuild )
: 0;
const EMessageBoxReturn ret = BuildMenuDialog_construct( projectList ); const EMessageBoxReturn ret = BuildMenuDialog_construct( projectList );
@ -986,14 +969,16 @@ void DoBuildMenu(){
class BuildMenuItem class BuildMenuItem
{ {
const char* m_name; /* using build index to pass build reference: it is okay for now, as we rebuild g_BuildMenuItems entirely on any modification
using build name before was faulty design, as builds may have equal names */
const size_t m_buildIdx;
public: public:
QAction* m_item; QAction* m_item;
BuildMenuItem( const char* name, QAction* item ) BuildMenuItem( size_t buildIdx )
: m_name( name ), m_item( item ){ : m_buildIdx( buildIdx ), m_item( nullptr ){
} }
void run() const { void run() const {
RunBSP( m_name ); RunBSP( m_buildIdx );
} }
typedef ConstMemberCaller<BuildMenuItem, &BuildMenuItem::run> RunCaller; typedef ConstMemberCaller<BuildMenuItem, &BuildMenuItem::run> RunCaller;
}; };
@ -1005,9 +990,10 @@ BuildMenuItems g_BuildMenuItems;
QMenu* g_bsp_menu; QMenu* g_bsp_menu;
void Build_constructMenu( QMenu* menu ){ void Build_constructMenu( QMenu* menu ){
size_t buildIdx{};
for ( const auto& [ name, commands ] : g_build_project ) for ( const auto& [ name, commands ] : g_build_project )
{ {
g_BuildMenuItems.push_back( BuildMenuItem( name.c_str(), 0 ) ); g_BuildMenuItems.push_back( BuildMenuItem( buildIdx++ ) );
if ( is_separator( name, commands ) ) { if ( is_separator( name, commands ) ) {
g_BuildMenuItems.back().m_item = menu->addSeparator(); g_BuildMenuItems.back().m_item = menu->addSeparator();
} }
@ -1094,8 +1080,6 @@ void BuildMenu_Destroy(){
void Build_runRecentExecutedBuild(){ void Build_runRecentExecutedBuild(){
if( Project_contains( g_build_project, g_lastExecutedBuild ) ) if( !g_build_project.empty() )
RunBSP( g_lastExecutedBuild->first.c_str() ); RunBSP( Project_find( g_build_project, g_lastExecutedBuild ) );
else if( !g_build_project.empty() )
RunBSP( g_build_project.cbegin()->first.c_str() );
} }

View File

@ -20,6 +20,8 @@
*/ */
#pragma once #pragma once
#include <cstddef>
void build_set_variable( const char* name, const char* value ); void build_set_variable( const char* name, const char* value );
void build_clear_variables(); void build_clear_variables();
@ -28,7 +30,7 @@ class CommandListener
public: public:
virtual void execute( const char* command ) = 0; virtual void execute( const char* command ) = 0;
}; };
void build_run( const char* name, CommandListener& listener ); void build_run( size_t buildIdx, CommandListener& listener );
void DoBuildMenu(); void DoBuildMenu();

View File

@ -234,7 +234,7 @@ public:
}; };
void RunBSP( const char* name ){ void RunBSP( size_t buildIdx ){
if( !g_region_active ) if( !g_region_active )
SaveMap(); SaveMap();
@ -256,7 +256,7 @@ void RunBSP( const char* name ){
bsp_init(); bsp_init();
ArrayCommandListener listener; ArrayCommandListener listener;
build_run( name, listener ); build_run( buildIdx, listener );
bool monitor = false; bool monitor = false;
for ( guint i = 0; i < listener.array()->len; ++i ) for ( guint i = 0; i < listener.array()->len; ++i )
if( strstr( (char*)g_ptr_array_index( listener.array(), i ), RADIANT_MONITOR_ADDRESS ) ) if( strstr( (char*)g_ptr_array_index( listener.array(), i ), RADIANT_MONITOR_ADDRESS ) )
@ -292,7 +292,7 @@ void RunBSP( const char* name ){
batchFile << "#!/bin/sh \n\n"; batchFile << "#!/bin/sh \n\n";
#endif #endif
BatchCommandListener listener( batchFile, g_WatchBSP0_DumpLog? junkpath : 0 ); BatchCommandListener listener( batchFile, g_WatchBSP0_DumpLog? junkpath : 0 );
build_run( name, listener ); build_run( buildIdx, listener );
written = true; written = true;
} }
} }

View File

@ -29,7 +29,7 @@
void Sys_SetTitle( const char *text, bool modified ); void Sys_SetTitle( const char *text, bool modified );
void RunBSP( const char* name ); void RunBSP( size_t buildIdx );
void QE_InitVFS(); void QE_InitVFS();