From 29c3fed3744e21e2ef4352e49ffbf66cecf1f2ba Mon Sep 17 00:00:00 2001 From: SaltySnail Date: Sat, 25 May 2024 20:32:07 +0200 Subject: [PATCH] fix #321 --- CMakeLists.txt | 4 +++- include/ChronoWrapper.h | 8 ++++++++ include/Common.h | 3 ++- src/ChronoWrapper.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/Common.cpp | 2 ++ src/TConfig.cpp | 4 ++++ src/THeartbeatThread.cpp | 11 ++++++++--- 7 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 include/ChronoWrapper.h create mode 100644 src/ChronoWrapper.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d23747..e2f0e89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ set(PRJ_HEADERS include/VehicleData.h include/Env.h include/Profiling.h + include/ChronoWrapper.h ) # add all source files (.cpp) to this, except the one with main() set(PRJ_SOURCES @@ -74,6 +75,7 @@ set(PRJ_SOURCES src/VehicleData.cpp src/Env.cpp src/Profiling.cpp + src/ChronoWrapper.cpp ) find_package(Lua REQUIRED) @@ -220,4 +222,4 @@ if(${PROJECT_NAME}_ENABLE_UNIT_TESTING) if(MSVC) target_link_options(${PROJECT_NAME}-tests PRIVATE "/SUBSYSTEM:CONSOLE") endif(MSVC) -endif() \ No newline at end of file +endif() diff --git a/include/ChronoWrapper.h b/include/ChronoWrapper.h new file mode 100644 index 0000000..f47c8f1 --- /dev/null +++ b/include/ChronoWrapper.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +namespace ChronoWrapper { + std::chrono::high_resolution_clock::duration TimeFromStringWithLiteral(const std::string time_str); +} diff --git a/include/Common.h b/include/Common.h index 46a954a..8f9a4f3 100644 --- a/include/Common.h +++ b/include/Common.h @@ -83,6 +83,7 @@ public: std::string HTTPServerIP { "127.0.0.1" }; bool HTTPServerUseSSL { false }; bool HideUpdateMessages { false }; + std::string UpdateReminderTime { "3h" }; [[nodiscard]] bool HasCustomIP() const { return !CustomIP.empty(); } }; @@ -151,7 +152,7 @@ private: static inline std::mutex mShutdownHandlersMutex {}; static inline std::deque mShutdownHandlers {}; - static inline Version mVersion { 3, 5, 0 }; + static inline Version mVersion { 4, 5, 0 }; }; void SplitString(std::string const& str, const char delim, std::vector& out); diff --git a/src/ChronoWrapper.cpp b/src/ChronoWrapper.cpp new file mode 100644 index 0000000..57e0a45 --- /dev/null +++ b/src/ChronoWrapper.cpp @@ -0,0 +1,36 @@ +#include "ChronoWrapper.h" +#include "Common.h" +#include + +std::chrono::high_resolution_clock::duration ChronoWrapper::TimeFromStringWithLiteral(const std::string time_str) +{ + // const std::regex time_regex(R"((\d+)(min|ms|us|ns|[dhs]))"); //i.e one of: "25ns, 6us, 256ms, 2s, 13min, 69h, 356d" will get matched (only available in newer C++ versions) + const std::regex time_regex(R"((\d+\.*\d*)(min|[dhs]))"); //i.e one of: "2.01s, 13min, 69h, 356.69d" will get matched + std::smatch match; + int64_t time_value; //TODO: make time_value a float and figure out how to return that as the correct amount of nanoseconds in high_precision_clock::duration + if (!std::regex_search(time_str, match, time_regex)) return std::chrono::nanoseconds(0); + time_value = stoi(match.str(1)); + beammp_debugf("Parsed time was: {}{}", time_value, match.str(2)); + if (match.str(2) == "d") { + return std::chrono::days(time_value); + } + else if (match.str(2) == "h") { + return std::chrono::hours(time_value); + } + else if (match.str(2) == "min") { + return std::chrono::minutes(time_value); + } + else if (match.str(2) == "s") { + return std::chrono::seconds(time_value); + } + // else if (match.str(2) == "ms") { + // return std::chrono::milliseconds(time_value); + // } + // else if (match.str(2) == "us") { + // return std::chrono::microseconds(time_value); + // } + // else if (match.str(2) == "ns") { + // return std::chrono::nanoseconds(time_value); + // } + return std::chrono::nanoseconds(0); +} diff --git a/src/Common.cpp b/src/Common.cpp index c2ac242..e2b0719 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "Compat.h" #include "CustomAssert.h" @@ -384,3 +385,4 @@ void SplitString(const std::string& str, const char delim, std::vector #include @@ -36,15 +37,17 @@ void THeartbeatThread::operator()() { static std::string Last; static std::chrono::high_resolution_clock::time_point LastNormalUpdateTime = std::chrono::high_resolution_clock::now(); + static std::chrono::high_resolution_clock::time_point LastUpdateReminderTime = std::chrono::high_resolution_clock::now(); bool isAuth = false; - size_t UpdateReminderCounter = 0; + std::chrono::high_resolution_clock::duration UpdateReminderTimePassed; + auto UpdateReminderTimeout = ChronoWrapper::TimeFromStringWithLiteral(Application::Settings.UpdateReminderTime); while (!Application::IsShuttingDown()) { - ++UpdateReminderCounter; Body = GenerateCall(); // a hot-change occurs when a setting has changed, to update the backend of that change. auto Now = std::chrono::high_resolution_clock::now(); bool Unchanged = Last == Body; auto TimePassed = (Now - LastNormalUpdateTime); + UpdateReminderTimePassed = (Now - LastUpdateReminderTime); auto Threshold = Unchanged ? 30 : 5; if (TimePassed < std::chrono::seconds(Threshold)) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -129,7 +132,9 @@ void THeartbeatThread::operator()() { if (isAuth || Application::Settings.Private) { Application::SetSubsystemStatus("Heartbeat", Application::Status::Good); } - if (!Application::Settings.HideUpdateMessages && UpdateReminderCounter % 5) { + // beammp_debugf("Update reminder time passed: {}, Update reminder time: {}", UpdateReminderTimePassed.count(), UpdateReminderTimeout.count()); + if (!Application::Settings.HideUpdateMessages && UpdateReminderTimePassed.count() > UpdateReminderTimeout.count()) { + LastUpdateReminderTime = std::chrono::high_resolution_clock::now(); Application::CheckForUpdates(); } }