From c0bea5e611012e31ea19eb482e70e86c028a79e6 Mon Sep 17 00:00:00 2001 From: jerrrrycho Date: Sun, 27 Sep 2026 19:04:23 +0200 Subject: [PATCH] refactor: sonar c++20 changes --- application/application.cpp | 7 +--- launcher/scenery_list.cpp | 2 +- launcher/vehicle_picker.cpp | 2 +- model/Model3d.cpp | 13 +++--- model/Texture.cpp | 6 +-- network/backend/asio.cpp | 6 ++- network/message.h | 16 ++++---- rendering/screenshot.cpp | 8 ++-- scene/sn_utils.cpp | 20 +++++---- simulation/simulationstateserializer.cpp | 5 ++- simulation/simulationtime.cpp | 3 +- utilities/Globals.cpp | 20 ++------- utilities/Logs.cpp | 3 +- utilities/utilities.cpp | 22 ++++++++++ utilities/utilities.h | 4 ++ vehicle/Driver.cpp | 52 ++++++++++-------------- vehicle/Driver.h | 6 +-- widgets/trainingcard.cpp | 22 +++++----- 18 files changed, 111 insertions(+), 106 deletions(-) diff --git a/application/application.cpp b/application/application.cpp index a6b88ae8..279cfd08 100644 --- a/application/application.cpp +++ b/application/application.cpp @@ -1479,11 +1479,8 @@ bool eu07_application::init_network() // TODO: sort out this timezone mess std::time_t utc_now = std::time(nullptr); - tm tm_local, tm_utc; - tm *tmp = std::localtime(&utc_now); - memcpy(&tm_local, tmp, sizeof(tm)); - tmp = std::gmtime(&utc_now); - memcpy(&tm_utc, tmp, sizeof(tm)); + std::tm const tm_local = local_tm(utc_now); + std::tm const tm_utc = utc_tm(utc_now); int64_t offset = tm_local.tm_hour * 3600 + tm_local.tm_min * 60 + tm_local.tm_sec - (tm_utc.tm_hour * 3600 + tm_utc.tm_min * 60 + tm_utc.tm_sec); diff --git a/launcher/scenery_list.cpp b/launcher/scenery_list.cpp index 0b49e80f..77f69a35 100644 --- a/launcher/scenery_list.cpp +++ b/launcher/scenery_list.cpp @@ -281,7 +281,7 @@ void ui::scenerylist_panel::draw_trainset(trainset_desc &trainset) for (auto &dyn_desc : trainset.vehicles) { deferred_image *mini = nullptr; - if (dyn_desc.skin && dyn_desc.skin->mini.get() != -1) + if (dyn_desc.skin && dyn_desc.skin->mini.get() != (GLuint)-1) mini = &dyn_desc.skin->mini; else mini = &placeholder_mini; diff --git a/launcher/vehicle_picker.cpp b/launcher/vehicle_picker.cpp index 88c40ef9..f7d3503f 100644 --- a/launcher/vehicle_picker.cpp +++ b/launcher/vehicle_picker.cpp @@ -270,7 +270,7 @@ bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, } GLuint tex = image->get(); - if (tex != -1) { + if (tex != (GLuint)-1) { glm::ivec2 size = image->size(); float width = 30.0f / size.y * size.x; ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); diff --git a/model/Model3d.cpp b/model/Model3d.cpp index 38f39080..fba07446 100644 --- a/model/Model3d.cpp +++ b/model/Model3d.cpp @@ -24,6 +24,8 @@ Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others #include "world/mtable.h" #include "scene/sn_utils.h" +#include + //--------------------------------------------------------------------------- using namespace Mtable; @@ -224,16 +226,13 @@ inline void readMatrix(cParser &parser, float4x4 &matrix) template void UserdataParse(cParser &parser, gfx::vertex_userdata &vertex) { + static_assert(sizeof(T) == sizeof(float), "userdata is stored as raw 32-bit values"); parser.getTokens(4); - union - { - T InType; - float FloatType; - } buf{}; for (int i = 0; i < 4; ++i) { - parser >> buf.InType; - vertex.data[i] = buf.FloatType; + T value{}; + parser >> value; + vertex.data[i] = std::bit_cast(value); } } diff --git a/model/Texture.cpp b/model/Texture.cpp index a5397663..5c1d852f 100644 --- a/model/Texture.cpp +++ b/model/Texture.cpp @@ -394,12 +394,12 @@ opengl_texture::make_from_memory(size_t width, size_t height, const uint8_t *raw void opengl_texture::update_from_memory(size_t width, size_t height, const uint8_t *raw) { - if (id != -1 && (width != data_width || height != data_height || GL_SRGB8_ALPHA8 != data_format || GL_RGBA != data_components)) + if (id != (GLuint)-1 && (width != data_width || height != data_height || GL_SRGB8_ALPHA8 != data_format || GL_RGBA != data_components)) { glDeleteTextures(1, &id); - id = -1; + id = (GLuint)-1; } - if (id == -1) + if (id == (GLuint)-1) { data_width = width; data_height = height; diff --git a/network/backend/asio.cpp b/network/backend/asio.cpp index 958b084e..c2d1364d 100644 --- a/network/backend/asio.cpp +++ b/network/backend/asio.cpp @@ -12,8 +12,10 @@ network::tcp::connection::connection(asio::io_context &io_ctx, bool client, size network::tcp::connection::~connection() { - m_socket.shutdown(m_socket.shutdown_both); - m_socket.close(); + // error_code overloads: the throwing ones would escape the destructor, e.g. when the peer is already gone + asio::error_code ec; + m_socket.shutdown(m_socket.shutdown_both, ec); + m_socket.close(ec); } void network::tcp::connection::disconnect() diff --git a/network/message.h b/network/message.h index 43ad13ec..871e833f 100644 --- a/network/message.h +++ b/network/message.h @@ -30,17 +30,17 @@ struct client_hello : public message virtual void serialize(std::ostream &stream) const override; virtual void deserialize(std::istream &stream) override; - int32_t version; - uint32_t start_packet; + int32_t version{}; + uint32_t start_packet{}; }; struct server_hello : public message { server_hello() : message(SERVER_HELLO) {} - uint32_t seed; - int64_t timestamp; - int64_t config; + uint32_t seed{}; + int64_t timestamp{}; + int64_t config{}; std::string scenario; virtual void serialize(std::ostream &stream) const override; @@ -62,9 +62,9 @@ struct frame_info : public request_command { frame_info() : request_command(FRAME_INFO) {} - double render_dt; - double dt; - double sync; + double render_dt{}; + double dt{}; + double sync{}; virtual void serialize(std::ostream &stream) const override; virtual void deserialize(std::istream &stream) override; diff --git a/rendering/screenshot.cpp b/rendering/screenshot.cpp index 285679b7..eb7e7aac 100644 --- a/rendering/screenshot.cpp +++ b/rendering/screenshot.cpp @@ -2,6 +2,7 @@ #include "rendering/screenshot.h" #include "utilities/Globals.h" #include "utilities/Logs.h" +#include "utilities/utilities.h" #include void screenshot_manager::screenshot_save_thread( char *img, int w, int h ) @@ -29,11 +30,8 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h ) } char datetime[64]; - time_t timer; - struct tm* tm_info; - time(&timer); - tm_info = localtime(&timer); - strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", tm_info); + std::tm const tm_info = local_tm(std::time(nullptr)); + strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", &tm_info); uint64_t perf; #ifdef _WIN32 diff --git a/scene/sn_utils.cpp b/scene/sn_utils.cpp index 71e6549c..08825d91 100644 --- a/scene/sn_utils.cpp +++ b/scene/sn_utils.cpp @@ -5,6 +5,8 @@ #include "stdafx.h" #include "scene/sn_utils.h" +#include + // sanity checks static_assert(std::numeric_limits::is_iec559, "IEEE754 required"); static_assert(sizeof(float) == 4, "Float must be 4 bytes"); @@ -17,7 +19,7 @@ uint16_t sn_utils::ld_uint16(std::istream &s) uint8_t buf[2]; s.read((char*)buf, 2); uint16_t v = buf[1] << 8 | buf[0]; - return reinterpret_cast(v); + return v; } // deserialize little endian uint32 @@ -26,7 +28,7 @@ uint32_t sn_utils::ld_uint32(std::istream &s) uint8_t buf[4]; s.read((char*)buf, 4); uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; - return reinterpret_cast(v); + return v; } // deserialize little endian int32 @@ -35,7 +37,7 @@ int32_t sn_utils::ld_int32(std::istream &s) uint8_t buf[4]; s.read((char*)buf, 4); uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; - return reinterpret_cast(v); + return static_cast(v); } // deserialize little endian uint64 @@ -47,7 +49,7 @@ uint64_t sn_utils::ld_uint64(std::istream &s) (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]; - return reinterpret_cast(v); + return v; } // deserialize little endian int64 @@ -59,7 +61,7 @@ int64_t sn_utils::ld_int64(std::istream &s) (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]; - return reinterpret_cast(v); + return static_cast(v); } // deserialize little endian ieee754 float32 @@ -68,7 +70,7 @@ float sn_utils::ld_float32(std::istream &s) uint8_t buf[4]; s.read((char*)buf, 4); uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; - return reinterpret_cast(v); + return std::bit_cast(v); } // deserialize little endian ieee754 float64 @@ -80,7 +82,7 @@ double sn_utils::ld_float64(std::istream &s) (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]; - return reinterpret_cast(v); + return std::bit_cast(v); } // deserialize null-terminated string @@ -195,7 +197,7 @@ void sn_utils::ls_int64(std::ostream &s, int64_t v) void sn_utils::ls_float32(std::ostream &s, float t) { - uint32_t v = reinterpret_cast(t); + uint32_t v = std::bit_cast(t); uint8_t buf[4]; buf[0] = v; buf[1] = v >> 8; @@ -206,7 +208,7 @@ void sn_utils::ls_float32(std::ostream &s, float t) void sn_utils::ls_float64(std::ostream &s, double t) { - uint64_t v = reinterpret_cast(t); + uint64_t v = std::bit_cast(t); uint8_t buf[8]; buf[0] = v; buf[1] = v >> 8; diff --git a/simulation/simulationstateserializer.cpp b/simulation/simulationstateserializer.cpp index ef7cd7db..99a733d3 100644 --- a/simulation/simulationstateserializer.cpp +++ b/simulation/simulationstateserializer.cpp @@ -27,6 +27,7 @@ http://mozilla.org/MPL/2.0/. #include "application/application.h" #include "rendering/renderer.h" #include "utilities/Logs.h" +#include "utilities/utilities.h" #include "editor/editorTerrainStreamer.hpp" namespace simulation { @@ -393,8 +394,8 @@ void state_serializer::init_time() { auto &time = simulation::Time.data(); if( true == Global.ScenarioTimeCurrent ) { // calculate time shift required to match scenario time with local clock - auto const *localtime = std::gmtime( &Global.starting_timestamp ); - Global.ScenarioTimeOffset = ( localtime->tm_hour * 60 + localtime->tm_min - ( time.wHour * 60 + time.wMinute ) ) / 60.f; + auto const localtime = utc_tm( Global.starting_timestamp ); + Global.ScenarioTimeOffset = ( localtime.tm_hour * 60 + localtime.tm_min - ( time.wHour * 60 + time.wMinute ) ) / 60.f; } else if( false == std::isnan( Global.ScenarioTimeOverride ) ) { // scenario time override takes precedence over scenario time offset diff --git a/simulation/simulationtime.cpp b/simulation/simulationtime.cpp index 52886709..f1683c53 100644 --- a/simulation/simulationtime.cpp +++ b/simulation/simulationtime.cpp @@ -32,7 +32,8 @@ scenario_time::init(std::time_t timestamp) { auto const requestedminute { requestedtime % 60 }; // cache requested elements, if any - std::tm *tms = std::gmtime(×tamp); + std::tm const tm = utc_tm(timestamp); + std::tm const *tms = &tm; m_time.wYear = tms->tm_year + 1900; m_time.wMonth = tms->tm_mon + 1; m_time.wDayOfWeek = tms->tm_wday; diff --git a/utilities/Globals.cpp b/utilities/Globals.cpp index f45b6b3e..47b04d18 100644 --- a/utilities/Globals.cpp +++ b/utilities/Globals.cpp @@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/. #include "simulation/simulationenvironment.h" #include "vehicle/Driver.h" #include "utilities/Logs.h" +#include "utilities/utilities.h" #include "Console.h" #include "scripting/PyInt.h" #include "utilities/Timer.h" @@ -26,15 +27,7 @@ http://mozilla.org/MPL/2.0/. void global_settings::LoadIniFile(std::string asFileName) { // initialize season data in case the main config file doesn't - std::time_t timenow = std::time(nullptr); - - std::tm tm{}; - -#ifdef _WIN32 - localtime_s(&tm, &timenow); -#else - localtime_r(&timenow, &tm); -#endif + std::tm const tm = local_tm(std::time(nullptr)); fMoveLight = tm.tm_yday + 1; // numer bieżącego dnia w roku simulation::Environment.compute_season(fMoveLight); @@ -513,14 +506,7 @@ bool global_settings::ConfigParseSimulation(cParser& Parser, const std::string& if (fMoveLight == 0.f) { - std::time_t timenow = std::time(nullptr); - std::tm tm{}; - -#ifdef _WIN32 - localtime_s(&tm, &timenow); -#else - localtime_r(&timenow, &tm); -#endif + std::tm const tm = local_tm(std::time(nullptr)); fMoveLight = tm.tm_yday + 1; } diff --git a/utilities/Logs.cpp b/utilities/Logs.cpp index 554a77b9..737d25d7 100644 --- a/utilities/Logs.cpp +++ b/utilities/Logs.cpp @@ -31,7 +31,8 @@ std::string filename_date() { #ifdef __unix__ timespec ts; clock_gettime(CLOCK_REALTIME, &ts); - tm *tms = localtime(&ts.tv_sec); + std::tm const tm = local_tm(ts.tv_sec); + std::tm const *tms = &tm; st.wYear = tms->tm_year; st.wMonth = tms->tm_mon; st.wDayOfWeek = tms->tm_wday; diff --git a/utilities/utilities.cpp b/utilities/utilities.cpp index 14e44897..efaf3e6c 100644 --- a/utilities/utilities.cpp +++ b/utilities/utilities.cpp @@ -426,6 +426,28 @@ std::time_t last_modified(std::string const &Filename) return 0; } +std::tm local_tm(std::time_t Time) +{ + std::tm tm{}; +#ifdef _WIN32 + localtime_s(&tm, &Time); +#else + localtime_r(&Time, &tm); +#endif + return tm; +} + +std::tm utc_tm(std::time_t Time) +{ + std::tm tm{}; +#ifdef _WIN32 + gmtime_s(&tm, &Time); +#else + gmtime_r(&Time, &tm); +#endif + return tm; +} + // potentially erases file extension from provided file name. returns: true if extension was removed, false otherwise bool erase_extension(std::string &Filename) { diff --git a/utilities/utilities.h b/utilities/utilities.h index 91d74e67..6e761380 100644 --- a/utilities/utilities.h +++ b/utilities/utilities.h @@ -220,6 +220,10 @@ std::pair FileExists(std::vector const &N // returns time of last modification for specified file std::time_t last_modified(std::string const &Filename); +// thread-safe replacements for std::localtime and std::gmtime, which hand out a pointer to shared static storage +std::tm local_tm(std::time_t Time); +std::tm utc_tm(std::time_t Time); + // potentially erases file extension from provided file name. returns: true if extension was removed, false otherwise bool erase_extension(std::string &Filename); diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index 9a6de859..bc911083 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -449,8 +449,8 @@ void TController::TableClear() iTableDirection = 0; // nieznany tLast = nullptr; fLastVel = -1.0; - SemNextIndex = -1; - SemNextStopIndex = -1; + SemNextIndex = npos; + SemNextStopIndex = npos; eSignSkip = nullptr; // nic nie pomijamy }; @@ -512,8 +512,8 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) sSpeedTable.clear(); iLast = -1; tLast = nullptr; //żaden nie sprawdzony - SemNextIndex = -1; - SemNextStopIndex = -1; + SemNextIndex = npos; + SemNextStopIndex = npos; */ if( VelSignalLast == 0.0 ) { // don't allow potential red light overrun keep us from reversing @@ -541,16 +541,16 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) else { if( iTableDirection == 0 ) { return; } // NOTE: belt and braces; TablePurger() used to leave these pointing past the end of the table - if( SemNextIndex != -1 + if( SemNextIndex != npos && SemNextIndex >= sSpeedTable.size() ) { - SemNextIndex = -1; + SemNextIndex = npos; } - if( SemNextStopIndex != -1 + if( SemNextStopIndex != npos && SemNextStopIndex >= sSpeedTable.size() ) { - SemNextStopIndex = -1; + SemNextStopIndex = npos; } // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) - if( SemNextStopIndex != -1 + if( SemNextStopIndex != npos && sSpeedTable[SemNextStopIndex].fVelNext == 0.0 ) { // znaleziono semafor lub tarczę lub tor z prędkością zero, trzeba sprawdzić czy to nadał semafor // jeśli jest następny semafor to sprawdzamy czy to on nadał zero @@ -614,23 +614,23 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) fDistance = newspeedpoint.fDist; // jeśli sygnał stop, to nie ma potrzeby dalej skanować SemNextStopIndex = iLast; - if (SemNextIndex == -1) { + if (SemNextIndex == npos) { SemNextIndex = iLast; } if (Global.iWriteLogEnabled & 8) { WriteLog("(stop signal from " - + (SemNextStopIndex != -1 ? sSpeedTable[SemNextStopIndex].GetName() : "unknown semaphor") + + (SemNextStopIndex != npos ? sSpeedTable[SemNextStopIndex].GetName() : "unknown semaphor") + ")"); } } else { if( true == newspeedpoint.IsProperSemaphor(OrderCurrentGet()) - && SemNextIndex == -1 ) { + && SemNextIndex == npos ) { SemNextIndex = iLast; // sprawdzamy czy pierwszy na drodze } if (Global.iWriteLogEnabled & 8) { WriteLog("(forward signal for " - + (SemNextIndex != -1 ? sSpeedTable[SemNextIndex].GetName() : "unknown semaphor") + + (SemNextIndex != npos ? sSpeedTable[SemNextIndex].GetName() : "unknown semaphor") + ")"); } } @@ -800,13 +800,13 @@ void TController::TableCheck(double fDistance) --iLast; } // a semaphor recorded beyond the switch went away with the discarded entries - if( SemNextIndex != -1 + if( SemNextIndex != npos && SemNextIndex >= sSpeedTable.size() ) { - SemNextIndex = -1; + SemNextIndex = npos; } - if( SemNextStopIndex != -1 + if( SemNextStopIndex != npos && SemNextStopIndex >= sSpeedTable.size() ) { - SemNextStopIndex = -1; + SemNextStopIndex = npos; } tLast = sSpeedTable[ i ].trTrack; TableTraceRoute( fDistance, pVehicles[ end::rear ] ); @@ -1387,13 +1387,13 @@ TController::TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPo if( Global.iWriteLogEnabled & 8 ) { WriteLog( "Speed table update for " + OwnerName() + ", passed semaphor " + sSpeedTable[ SemNextIndex ].GetName() ); } - SemNextIndex = -1; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze zmiennej sprawdzającej dla skanowania w przód + SemNextIndex = npos; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze zmiennej sprawdzającej dla skanowania w przód } if( SemNextStopIndex == Pointindex ) { if( Global.iWriteLogEnabled & 8 ) { WriteLog( "Speed table update for " + OwnerName() + ", passed semaphor " + sSpeedTable[ SemNextStopIndex ].GetName() ); } - SemNextStopIndex = -1; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze zmiennej sprawdzającej dla skanowania w przód + SemNextStopIndex = npos; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze zmiennej sprawdzającej dla skanowania w przód } switch( Point.evEvent->input_command() ) { // TBD, TODO: expand emergency_brake handling to a more generic security system signal @@ -1461,13 +1461,13 @@ TController::TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPo } // jeśli jest mienięty poprzedni semafor a wcześniej // byl nowy to go dorzucamy do zmiennej, żeby cały czas widział najbliższy - if( SemNextIndex == -1 ) { + if( SemNextIndex == npos ) { SemNextIndex = Pointindex; if( Global.iWriteLogEnabled & 8 ) { WriteLog( "Speed table update for " + OwnerName() + ", next semaphor is " + sSpeedTable[ SemNextIndex ].GetName() ); } } - if( SemNextStopIndex == -1 + if( SemNextStopIndex == npos || ( sSpeedTable[SemNextStopIndex].fVelNext != 0 && Point.fVelNext == 0 ) ) { SemNextStopIndex = Pointindex; @@ -1926,17 +1926,9 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, fActionTime = -5.0; }; -void TController::CloseLog() -{ - if (WriteLogFlag) - { - LogFile.close(); - } -}; - TController::~TController() { // wykopanie mechanika z roboty - CloseLog(); + // LogFile is closed by its own destructor }; // zamiana kodu rozkazu na opis diff --git a/vehicle/Driver.h b/vehicle/Driver.h index e7c4fac0..b76dbf08 100644 --- a/vehicle/Driver.h +++ b/vehicle/Driver.h @@ -542,8 +542,9 @@ private: double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze TTrack *tLast = nullptr; // ostatni analizowany tor basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu - std::size_t SemNextIndex{ std::size_t( -1 ) }; - std::size_t SemNextStopIndex{ std::size_t( -1 ) }; + static constexpr std::size_t npos{ std::size_t( -1 ) }; + std::size_t SemNextIndex{ npos }; + std::size_t SemNextStopIndex{ npos }; double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2] neighbour_data Obstacle; // nearest vehicle detected ahead on current route @@ -622,7 +623,6 @@ private: // logs // methods void PhysicsLog(); - void CloseLog(); // members std::ofstream LogFile; // zapis parametrow fizycznych double LastUpdatedTime = 0.0; // czas od ostatniego logu diff --git a/widgets/trainingcard.cpp b/widgets/trainingcard.cpp index d4d11e5b..27fb0965 100644 --- a/widgets/trainingcard.cpp +++ b/widgets/trainingcard.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "widgets/trainingcard.h" #include "simulation/simulation.h" +#include "utilities/utilities.h" #ifdef __linux__ #include @@ -46,12 +47,11 @@ void trainingcard_panel::clear() void trainingcard_panel::save_thread_func() { - std::tm *tm = std::localtime(&(*start_time_wall)); - std::string date = std::to_string(tm->tm_year + 1900) + "-" + std::to_string(tm->tm_mon + 1) + "-" + std::to_string(tm->tm_mday); - std::string from = std::to_string(tm->tm_hour) + ":" + std::to_string(tm->tm_min); - std::time_t now = std::time(nullptr); - tm = std::localtime(&now); - std::string to = std::to_string(tm->tm_hour) + ":" + std::to_string(tm->tm_min); + std::tm tm = local_tm(*start_time_wall); + std::string date = std::to_string(tm.tm_year + 1900) + "-" + std::to_string(tm.tm_mon + 1) + "-" + std::to_string(tm.tm_mday); + std::string from = std::to_string(tm.tm_hour) + ":" + std::to_string(tm.tm_min); + tm = local_tm(std::time(nullptr)); + std::string to = std::to_string(tm.tm_hour) + ":" + std::to_string(tm.tm_min); std::fstream temp("reports/" + recording_timestamp + ".html", std::ios_base::out | std::ios_base::binary); std::fstream input("report_template.html", std::ios_base::in | std::ios_base::binary); @@ -121,9 +121,9 @@ void trainingcard_panel::render_contents() if (start_time_wall) { - std::tm *tm = std::localtime(&(*start_time_wall)); - std::string rep = "Czas rozpoczęcia: " + std::to_string(tm->tm_year + 1900) + "-" + std::to_string(tm->tm_mon + 1) + "-" + std::to_string(tm->tm_mday) + " " + std::to_string(tm->tm_hour) + - ":" + std::to_string(tm->tm_min); + std::tm const tm = local_tm(*start_time_wall); + std::string rep = "Czas rozpoczęcia: " + std::to_string(tm.tm_year + 1900) + "-" + std::to_string(tm.tm_mon + 1) + "-" + std::to_string(tm.tm_mday) + " " + std::to_string(tm.tm_hour) + + ":" + std::to_string(tm.tm_min); ImGui::TextUnformatted(rep.c_str()); } @@ -159,8 +159,8 @@ void trainingcard_panel::render_contents() if (ImGui::Button("Rozpocznij szkolenie")) { start_time_wall = std::time(nullptr); - std::tm *tm = std::localtime(&(*start_time_wall)); - recording_timestamp = std::to_string(tm->tm_year + 1900) + std::to_string(tm->tm_mon + 1) + std::to_string(tm->tm_mday) + std::to_string(tm->tm_hour) + std::to_string(tm->tm_min) + "_" + + std::tm const tm = local_tm(*start_time_wall); + recording_timestamp = std::to_string(tm.tm_year + 1900) + std::to_string(tm.tm_mon + 1) + std::to_string(tm.tm_mday) + std::to_string(tm.tm_hour) + std::to_string(tm.tm_min) + "_" + std::string(trainee_name.c_str()) + "_" + std::string(instructor_name.c_str()); int ret = StartRecording();