Codechange: introduce a framework for all our timers

IntervalTimer and TimeoutTimer use RAII, and can be used to replace
all the time-based timeouts, lag-detection, "execute every N" we
have.
As it uses RAII, you can safely use it as static variable, class
member, temporary variable, etc. As soon as it goes out-of-scope,
it will be safely removed.
This allows for much easier to read code when it comes to intervals.
This commit is contained in:
Patric Stout
2023-04-13 17:16:48 +02:00
committed by Patric Stout
parent 730687080a
commit 5e1bcee39b
12 changed files with 591 additions and 85 deletions

View File

@@ -39,6 +39,8 @@
#include "network/network_func.h"
#include "guitimer_func.h"
#include "news_func.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "safeguards.h"
@@ -3076,6 +3078,34 @@ void CallWindowRealtimeTickEvent(uint delta_ms)
}
}
/** Update various of window-related information on a regular interval. */
static IntervalTimer<TimerWindow> window_interval(std::chrono::milliseconds(30), [](auto) {
extern int _caret_timer;
_caret_timer += 3;
CursorTick();
HandleKeyScrolling();
HandleAutoscroll();
DecreaseWindowCounters();
});
/** Blink the window highlight colour constantly. */
static IntervalTimer<TimerWindow> highlight_interval(std::chrono::milliseconds(450), [](auto) {
_window_highlight_colour = !_window_highlight_colour;
});
/** Blink all windows marked with a white border. */
static IntervalTimer<TimerWindow> white_border_interval(std::chrono::milliseconds(30), [](auto) {
if (_network_dedicated) return;
for (Window *w : Window::Iterate()) {
if ((w->flags & WF_WHITE_BORDER) && --w->white_border_timer == 0) {
CLRBITS(w->flags, WF_WHITE_BORDER);
w->SetDirty();
}
}
});
/**
* Update the continuously changing contents of the windows, such as the viewports
*/
@@ -3093,56 +3123,21 @@ void UpdateWindows()
ProcessPendingPerformanceMeasurements();
TimerManager<TimerWindow>::Elapsed(std::chrono::milliseconds(delta_ms));
CallWindowRealtimeTickEvent(delta_ms);
static GUITimer network_message_timer = GUITimer(1);
if (network_message_timer.Elapsed(delta_ms)) {
network_message_timer.SetInterval(1000);
NetworkChatMessageLoop();
}
/* Process invalidations before anything else. */
for (Window *w : Window::Iterate()) {
w->ProcessScheduledInvalidations();
w->ProcessHighlightedInvalidations();
}
static GUITimer window_timer = GUITimer(1);
if (window_timer.Elapsed(delta_ms)) {
if (_network_dedicated) window_timer.SetInterval(MILLISECONDS_PER_TICK);
extern int _caret_timer;
_caret_timer += 3;
CursorTick();
HandleKeyScrolling();
HandleAutoscroll();
DecreaseWindowCounters();
}
static GUITimer highlight_timer = GUITimer(1);
if (highlight_timer.Elapsed(delta_ms)) {
highlight_timer.SetInterval(450);
_window_highlight_colour = !_window_highlight_colour;
}
if (!_pause_mode || _game_mode == GM_EDITOR || _settings_game.construction.command_pause_level > CMDPL_NO_CONSTRUCTION) MoveAllTextEffects(delta_ms);
/* Skip the actual drawing on dedicated servers without screen.
* But still empty the invalidation queues above. */
if (_network_dedicated) return;
if (window_timer.HasElapsed()) {
window_timer.SetInterval(MILLISECONDS_PER_TICK);
for (Window *w : Window::Iterate()) {
if ((w->flags & WF_WHITE_BORDER) && --w->white_border_timer == 0) {
CLRBITS(w->flags, WF_WHITE_BORDER);
w->SetDirty();
}
}
}
DrawDirtyBlocks();
for (Window *w : Window::Iterate()) {