diff --git a/rendering/nullrenderer.h b/rendering/nullrenderer.h index 2a7ef039..7ecb57bf 100644 --- a/rendering/nullrenderer.h +++ b/rendering/nullrenderer.h @@ -36,7 +36,7 @@ private: }; // user interface backend which draws nothing: imgui still builds its frames, so the ui code runs as usual -class null_imgui_renderer : public imgui_renderer { +class null_imgui_renderer final : public imgui_renderer { public: bool Init() override { return true; } void Shutdown() override { /* null implementation, nothing to do */ } diff --git a/simulation/simulationtest.cpp b/simulation/simulationtest.cpp index 8d57505f..45aa513f 100644 --- a/simulation/simulationtest.cpp +++ b/simulation/simulationtest.cpp @@ -45,19 +45,20 @@ test_manager &test() std::string_view to_string(test_result const Result) { + using enum test_result; switch (Result) { - case test_result::pass: return "pass"; - case test_result::fail: return "fail"; - case test_result::signal_passed_at_danger: return "signal passed at danger"; - case test_result::timeout: return "timeout"; - case test_result::standstill: return "standstill"; - case test_result::error: return "error"; + case pass: return "pass"; + case fail: return "fail"; + case signal_passed_at_danger: return "signal passed at danger"; + case timeout: return "timeout"; + case standstill: return "standstill"; + case error: return "error"; } return "unknown"; } -void test_manager::init_result_cell() +void test_manager::init_result_cell() const { auto cell { std::make_unique(scene::node_data{0, -1, std::string(result_cell), "memcell"}) }; // neither of the reported values, so that a cell nobody wrote to says nothing diff --git a/simulation/simulationtest.h b/simulation/simulationtest.h index f47f408b..a58e9ae2 100644 --- a/simulation/simulationtest.h +++ b/simulation/simulationtest.h @@ -39,7 +39,7 @@ public: static constexpr double frame_step { 0.03 }; // creates the result cell; called with the other scripting interface cells, before the scenery is read - void init_result_cell(); + void init_result_cell() const; // the simulation is ready: start the clocks void start(); // checks the end conditions after a simulation frame of Deltatime seconds diff --git a/utilities/Globals.cpp b/utilities/Globals.cpp index 2516da29..3a9e1014 100644 --- a/utilities/Globals.cpp +++ b/utilities/Globals.cpp @@ -456,10 +456,10 @@ bool global_settings::ConfigParseInput(cParser& Parser, const std::string& token return false; } -bool global_settings::ConfigParseTest(cParser& Parser, const std::string& token) +bool global_settings::ConfigParseTest(cParser& Parser, std::string_view const Token) { // integration test limits, usually given in the config block of a test scenery - if (token == "test.timeout") + if (Token == "test.timeout") { double value{ test.timeout }; ParseOne(Parser, value); @@ -468,26 +468,26 @@ bool global_settings::ConfigParseTest(cParser& Parser, const std::string& token) return true; } - if (token == "test.standstill") + if (Token == "test.standstill") { ParseOne(Parser, test.standstill); test.standstill = std::max(0.0, test.standstill); return true; } - if (token == "test.pass_on_standstill") + if (Token == "test.pass_on_standstill") { ParseOne(Parser, test.pass_on_standstill); return true; } - if (token == "test.fail_if_stop_overran") + if (Token == "test.fail_if_stop_overran") { ParseOne(Parser, test.fail_if_stop_overran); return true; } - if (token == "test.no_movement_before_pass") + if (Token == "test.no_movement_before_pass") { ParseOne(Parser, test.no_movement_before_pass); return true; diff --git a/utilities/Globals.h b/utilities/Globals.h index a6a9e122..11d14e34 100644 --- a/utilities/Globals.h +++ b/utilities/Globals.h @@ -95,7 +95,8 @@ struct global_settings { bool fail_if_stop_overran{ true }; // a train passing a signal at stop ends the test as failed; with false it's only logged bool no_movement_before_pass{ true }; // a pass waits until every vehicle stands still; with false it ends the test at once bool timeout_from_command_line{ false }; // --test-timeout given, the scenery doesn't override it - } test; + }; + test_settings test; bool editor_tracks{ false }; // F3 track workspace: draw and pick tracks without the scenery draw-range cap int iConvertModels{ 0 }; // tworzenie plików binarnych int iConvertIndexRange{ 1000 }; // range of duplicate vertex scan @@ -387,7 +388,7 @@ struct global_settings { bool ConfigParseNetwork(cParser& Parser, const std::string& token); bool ConfigParseHardware(cParser& Parser, const std::string& token); bool ConfigParseDebug(cParser& Parser, const std::string& token); - bool ConfigParseTest(cParser& Parser, const std::string& token); + bool ConfigParseTest(cParser& Parser, std::string_view Token); bool ConfigParse_gfx( cParser &parser, std::string_view const Token ); // sends basic content of the class in legacy (text) format to provided stream void diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index c0614923..fe09fb24 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -768,7 +768,8 @@ void TController::TableCheck(double fDistance) { // aktualizacja rekordów z wyjątkiem ostatniego if (sSpeedTable[i].iFlags & spEnabled) // jeśli pozycja istotna { - if (UpdateSpeedPosition(sSpeedTable[i])) + auto const passedbefore { TestFlag( sSpeedTable[ i ].iFlags, spElapsed ) }; + if (sSpeedTable[i].Update()) { if( Global.iWriteLogEnabled & 8 ) { WriteLog( "Speed table for " + OwnerName() + " detected switch change at " + sSpeedTable[ i ].trTrack->name() + " (generating fresh trace)" ); @@ -794,6 +795,8 @@ void TController::TableCheck(double fDistance) // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy break; } + // a switch is a track, the update of a signal never ends the loop above + CheckSignalPassedAtDanger( sSpeedTable[ i ], passedbefore ); if (sSpeedTable[i].iFlags & spTrack) // jeśli odcinek { if( sSpeedTable[ i ].fDist + sSpeedTable[ i ].trTrack->Length() < -fLength ) // a skład wyjechał całą długością poza @@ -817,8 +820,10 @@ void TController::TableCheck(double fDistance) } } } - // aktualizacja ostatniego; a signal at stop often is the last, the scan doesn't go past it - UpdateSpeedPosition(sSpeedTable[iLast]); + auto const lastpassedbefore { TestFlag( sSpeedTable[ iLast ].iFlags, spElapsed ) }; + sSpeedTable[iLast].Update(); // aktualizacja ostatniego + // a signal at stop often is the last, the scan doesn't go past it + CheckSignalPassedAtDanger( sSpeedTable[ iLast ], lastpassedbefore ); // WriteLog("TableCheck: Upate last track. Dist=" + AnsiString(sSpeedTable[iLast].fDist)); if( sSpeedTable[ iLast ].fDist < fDistance ) { TableTraceRoute( fDistance, pVehicles[ end::rear ] ); // doskanowanie dalszego odcinka @@ -843,17 +848,14 @@ bool is_signal_at_stop( TSpeedPos const &Point ) } // namespace -bool TController::UpdateSpeedPosition( TSpeedPos &Point ) const +void TController::CheckSignalPassedAtDanger( TSpeedPos const &Point, bool const Passedbefore ) const { - auto const passedbefore { TestFlag( Point.iFlags, spElapsed ) }; - auto const switchchanged { Point.Update() }; - if( false == passedbefore + if( false == Passedbefore && TestFlag( Point.iFlags, spElapsed ) && is_signal_at_stop( Point ) && ( mvOccupied->CategoryFlag & 1 ) != 0 ) { // railway only simulation::test().signal_passed_at_danger( OwnerName(), Point.evEvent->m_name ); } - return switchchanged; } auto const passengerstopmaxdistance { 400.0 }; // maximum allowed distance between passenger stop point and consist head diff --git a/vehicle/Driver.h b/vehicle/Driver.h index 8f2015f2..dfa63c08 100644 --- a/vehicle/Driver.h +++ b/vehicle/Driver.h @@ -519,9 +519,9 @@ private: bool TableNotFound( basic_event const *Event, double const Distance ) const; void TableTraceRoute( double fDistance, TDynamicObject *pVehicle ); void TableCheck( double fDistance ); - // updates a position of the speed table, returns true when a switch on it changed (TSpeedPos::Update). + // called after TSpeedPos::Update() of a position of the speed table, with its spElapsed flag from before it: // reports the head of the train going past it, if it's a signal showing stop - bool UpdateSpeedPosition( TSpeedPos &Point ) const; + void CheckSignalPassedAtDanger( TSpeedPos const &Point, bool Passedbefore ) const; TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc ); bool TableUpdateStopPoint( TCommandType &Command, TSpeedPos &Point, double const Signaldistance ); bool TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPos &Point, double &Signaldistance, int const Pointindex );