Codechange: migrate all Window-related timers to the new framework

This means we also say goodbye to GUITimers.
pull/544/head
Patric Stout 1 year ago committed by Patric Stout
parent 5e1bcee39b
commit 1ba4dcc924

@ -192,7 +192,6 @@ add_files(
group_gui.h
group_type.h
gui.h
guitimer_func.h
heightmap.cpp
heightmap.h
highscore.cpp

@ -42,6 +42,8 @@
#include "group_cmd.h"
#include "misc_cmd.h"
#include "object_cmd.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/company_widget.h"
@ -519,15 +521,18 @@ struct CompanyFinancesWindow : Window {
}
}
void OnHundredthTick() override
{
/**
* Check on a regular interval if the maximum amount of money has changed.
* If it has, rescale the window to fit the new amount.
*/
IntervalTimer<TimerWindow> rescale_interval = {std::chrono::seconds(3), [this](auto) {
const Company *c = Company::Get((CompanyID)this->window_number);
if (c->money > CompanyFinancesWindow::max_money) {
CompanyFinancesWindow::max_money = std::max(c->money * 2, CompanyFinancesWindow::max_money * 4);
this->SetupWidgets();
this->ReInit();
}
}
}};
};
/** First conservative estimate of the maximum amount of money */
@ -2679,11 +2684,10 @@ struct CompanyWindow : Window
}
}
void OnHundredthTick() override
{
/* redraw the window every now and then */
/** Redraw the window on a regular interval. */
IntervalTimer<TimerWindow> redraw_interval = {std::chrono::seconds(3), [this](auto) {
this->SetDirty();
}
}};
void OnPlaceObject(Point pt, TileIndex tile) override
{

@ -12,7 +12,6 @@
#include "window_gui.h"
#include "console_gui.h"
#include "console_internal.h"
#include "guitimer_func.h"
#include "window_func.h"
#include "string_func.h"
#include "strings_func.h"
@ -21,6 +20,8 @@
#include "console_func.h"
#include "rev.h"
#include "video/video_driver.hpp"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include <deque>
#include <string>
@ -115,14 +116,12 @@ struct IConsoleWindow : Window
static size_t scroll;
int line_height; ///< Height of one line of text in the console.
int line_offset;
GUITimer truncate_timer;
IConsoleWindow() : Window(&_console_window_desc)
{
_iconsole_mode = ICONSOLE_OPENED;
this->InitNested(0);
this->truncate_timer.SetInterval(3000);
ResizeWindow(this, _screen.width, _screen.height / 3);
}
@ -186,10 +185,8 @@ struct IConsoleWindow : Window
}
}
void OnRealtimeTick(uint delta_ms) override
{
if (this->truncate_timer.CountElapsed(delta_ms) == 0) return;
/** Check on a regular interval if the console buffer needs truncating. */
IntervalTimer<TimerWindow> truncate_interval = {std::chrono::seconds(3), [this](auto) {
assert(this->height >= 0 && this->line_height > 0);
size_t visible_lines = (size_t)(this->height / this->line_height);
@ -198,7 +195,7 @@ struct IConsoleWindow : Window
IConsoleWindow::scroll = std::min<size_t>(IConsoleWindow::scroll, max_scroll);
this->SetDirty();
}
}
}};
void OnMouseLoop() override
{

@ -15,7 +15,8 @@
#include "company_type.h"
#include "command_type.h"
#include "core/geometry_type.hpp"
#include "guitimer_func.h"
#include <chrono>
struct GRFFile;
@ -30,7 +31,7 @@ enum WarningLevel {
/** The data of the error message. */
class ErrorMessageData {
protected:
GUITimer display_timer; ///< Timer before closing the message.
bool is_critical; ///< Whether the error message is critical.
uint64 decode_params[20]; ///< Parameters of the message strings.
const char *strings[20]; ///< Copies of raw strings that were used.
const GRFFile *textref_stack_grffile; ///< NewGRF that filled the #TextRefStack for the error message.
@ -45,7 +46,7 @@ protected:
public:
ErrorMessageData(const ErrorMessageData &data);
~ErrorMessageData();
ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr, StringID extra_msg = INVALID_STRING_ID);
ErrorMessageData(StringID summary_msg, StringID detailed_msg, bool is_critical = false, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr, StringID extra_msg = INVALID_STRING_ID);
/* Remove the copy assignment, as the default implementation will not do the right thing. */
ErrorMessageData &operator=(ErrorMessageData &rhs) = delete;

@ -21,6 +21,8 @@
#include "window_func.h"
#include "console_func.h"
#include "window_gui.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/error_widget.h"
@ -71,7 +73,7 @@ static WindowDesc _errmsg_face_desc(
* @param data The data to copy.
*/
ErrorMessageData::ErrorMessageData(const ErrorMessageData &data) :
display_timer(data.display_timer), textref_stack_grffile(data.textref_stack_grffile), textref_stack_size(data.textref_stack_size),
is_critical(data.is_critical), textref_stack_grffile(data.textref_stack_grffile), textref_stack_size(data.textref_stack_size),
summary_msg(data.summary_msg), detailed_msg(data.detailed_msg), extra_msg(data.extra_msg), position(data.position), face(data.face)
{
memcpy(this->textref_stack, data.textref_stack, sizeof(this->textref_stack));
@ -95,7 +97,7 @@ ErrorMessageData::~ErrorMessageData()
* Display an error message in a window.
* @param summary_msg General error message showed in first line. Must be valid.
* @param detailed_msg Detailed error message showed in second line. Can be INVALID_STRING_ID.
* @param duration The amount of time to show this error message.
* @param is_critical Whether the error is critical. Critical messages never go away on their own.
* @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile.
* @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile.
* @param textref_stack_grffile NewGRF that provides the #TextRefStack for the error message.
@ -103,7 +105,8 @@ ErrorMessageData::~ErrorMessageData()
* @param textref_stack Values to put on the #TextRefStack.
* @param extra_msg Extra error message showed in third line. Can be INVALID_STRING_ID.
*/
ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) :
ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, bool is_critical, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) :
is_critical(is_critical),
textref_stack_grffile(textref_stack_grffile),
textref_stack_size(textref_stack_size),
summary_msg(summary_msg),
@ -120,8 +123,6 @@ ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg,
if (textref_stack_size > 0) MemCpyT(this->textref_stack, textref_stack, textref_stack_size);
assert(summary_msg != INVALID_STRING_ID);
this->display_timer.SetInterval(duration * 3000);
}
/**
@ -187,11 +188,22 @@ private:
uint height_summary; ///< Height of the #summary_msg string in pixels in the #WID_EM_MESSAGE widget.
uint height_detailed; ///< Height of the #detailed_msg string in pixels in the #WID_EM_MESSAGE widget.
uint height_extra; ///< Height of the #extra_msg string in pixels in the #WID_EM_MESSAGE widget.
TimeoutTimer<TimerWindow> display_timeout;
public:
ErrmsgWindow(const ErrorMessageData &data) : Window(data.HasFace() ? &_errmsg_face_desc : &_errmsg_desc), ErrorMessageData(data)
ErrmsgWindow(const ErrorMessageData &data) :
Window(data.HasFace() ? &_errmsg_face_desc : &_errmsg_desc),
ErrorMessageData(data),
display_timeout(std::chrono::seconds(3 * _settings_client.gui.errmsg_duration), [this]() {
this->Close();
})
{
this->InitNested();
/* Only start the timeout if the message is not critical. */
if (!this->is_critical) {
this->display_timeout.Reset();
}
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
@ -316,14 +328,7 @@ public:
void OnMouseLoop() override
{
/* Disallow closing the window too easily, if timeout is disabled */
if (_right_button_down && !this->display_timer.HasElapsed()) this->Close();
}
void OnRealtimeTick(uint delta_ms) override
{
if (this->display_timer.CountElapsed(delta_ms) == 0) return;
this->Close();
if (_right_button_down && !this->is_critical) this->Close();
}
void Close() override
@ -339,7 +344,7 @@ public:
*/
bool IsCritical()
{
return this->display_timer.HasElapsed();
return this->is_critical;
}
};
@ -428,12 +433,12 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel
IConsolePrint(wl == WL_WARNING ? CC_WARNING : CC_ERROR, buf);
}
bool no_timeout = wl == WL_CRITICAL;
bool is_critical = wl == WL_CRITICAL;
if (_game_mode == GM_BOOTSTRAP) return;
if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return;
if (_settings_client.gui.errmsg_duration == 0 && !is_critical) return;
ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack, extra_msg);
ErrorMessageData data(summary_msg, detailed_msg, is_critical, x, y, textref_stack_grffile, textref_stack_size, textref_stack, extra_msg);
data.CopyOutDParams();
ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0);

@ -17,12 +17,13 @@
#include "strings_func.h"
#include "console_func.h"
#include "console_type.h"
#include "guitimer_func.h"
#include "company_base.h"
#include "ai/ai_info.hpp"
#include "ai/ai_instance.hpp"
#include "game/game.hpp"
#include "game/game_instance.hpp"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/framerate_widget.h"
@ -410,7 +411,6 @@ static const NWidgetPart _framerate_window_widgets[] = {
struct FramerateWindow : Window {
bool small;
bool showing_memory;
GUITimer next_update;
int num_active;
int num_displayed;
@ -456,7 +456,6 @@ struct FramerateWindow : Window {
this->showing_memory = true;
this->UpdateData();
this->num_displayed = this->num_active;
this->next_update.SetInterval(100);
/* Window is always initialised to MIN_ELEMENTS height, resize to contain num_displayed */
ResizeWindow(this, 0, (std::max(MIN_ELEMENTS, this->num_displayed) - MIN_ELEMENTS) * FONT_HEIGHT_NORMAL);
@ -464,22 +463,21 @@ struct FramerateWindow : Window {
void OnRealtimeTick(uint delta_ms) override
{
bool elapsed = this->next_update.Elapsed(delta_ms);
/* Check if the shaded state has changed, switch caption text if it has */
if (this->small != this->IsShaded()) {
this->small = this->IsShaded();
this->GetWidget<NWidgetLeaf>(WID_FRW_CAPTION)->SetDataTip(this->small ? STR_FRAMERATE_CAPTION_SMALL : STR_FRAMERATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
elapsed = true;
}
if (elapsed) {
this->UpdateData();
this->SetDirty();
this->next_update.SetInterval(100);
}
}
/** Update the window on a regular interval. */
IntervalTimer<TimerWindow> update_interval = {std::chrono::milliseconds(100), [this](auto) {
this->UpdateData();
this->SetDirty();
}};
void UpdateData()
{
double gl_rate = _pf_data[PFE_GAMELOOP].GetRate();
@ -754,7 +752,6 @@ static const NWidgetPart _frametime_graph_window_widgets[] = {
struct FrametimeGraphWindow : Window {
int vertical_scale; ///< number of TIMESTAMP_PRECISION units vertically
int horizontal_scale; ///< number of half-second units horizontally
GUITimer next_scale_update; ///< interval for next scale update
PerformanceElement element; ///< what element this window renders graph for
Dimension graph_size; ///< size of the main graph area (excluding axis labels)
@ -764,9 +761,9 @@ struct FrametimeGraphWindow : Window {
this->element = (PerformanceElement)number;
this->horizontal_scale = 4;
this->vertical_scale = TIMESTAMP_PRECISION / 10;
this->next_scale_update.SetInterval(1);
this->InitNested(number);
this->UpdateScale();
}
void SetStringParameters(int widget) const override
@ -882,14 +879,14 @@ struct FrametimeGraphWindow : Window {
this->SelectVerticalScale(peak_value);
}
/** Update the scaling on a regular interval. */
IntervalTimer<TimerWindow> update_interval = {std::chrono::milliseconds(500), [this](auto) {
this->UpdateScale();
}};
void OnRealtimeTick(uint delta_ms) override
{
this->SetDirty();
if (this->next_scale_update.Elapsed(delta_ms)) {
this->next_scale_update.SetInterval(500);
this->UpdateScale();
}
}
/** Scale and interpolate a value from a source range into a destination range */

@ -15,6 +15,8 @@
#include "../network/network.h"
#include "../network/network_content.h"
#include "../widgets/dropdown_func.h"
#include "../timer/timer.h"
#include "../timer/timer_window.h"
#include "game.hpp"
#include "game_gui.hpp"
@ -83,7 +85,6 @@ struct GSConfigWindow : public Window {
bool clicked_increase; ///< Whether we clicked the increase or decrease button.
bool clicked_dropdown; ///< Whether the dropdown is open.
bool closing_dropdown; ///< True, if the dropdown list is currently closing.
GUITimer timeout; ///< Timeout for unclicking the button.
int clicked_row; ///< The clicked row of settings.
Scrollbar *vscroll; ///< Cache of the vertical scrollbar.
typedef std::vector<const ScriptConfigItem *> VisibleSettingsList; ///< typdef for a vector of script settings
@ -92,8 +93,7 @@ struct GSConfigWindow : public Window {
GSConfigWindow() : Window(&_gs_config_desc),
clicked_button(-1),
clicked_dropdown(false),
closing_dropdown(false),
timeout(0)
closing_dropdown(false)
{
this->gs_config = GameConfig::GetConfig();
@ -336,7 +336,7 @@ struct GSConfigWindow : public Window {
if (new_val != old_val) {
this->gs_config->SetSetting(config_item.name, new_val);
this->clicked_button = num;
this->timeout.SetInterval(150);
this->unclick_timeout.Reset();
}
} else if (!bool_item && !config_item.complete_labels) {
/* Display a query box so users can enter a custom value. */
@ -387,13 +387,11 @@ struct GSConfigWindow : public Window {
this->vscroll->SetCapacityFromWidget(this, WID_GSC_SETTINGS);
}
void OnRealtimeTick(uint delta_ms) override
{
if (this->timeout.Elapsed(delta_ms)) {
this->clicked_button = -1;
this->SetDirty();
}
}
/** When reset, unclick the button after a small timeout. */
TimeoutTimer<TimerWindow> unclick_timeout = {std::chrono::milliseconds(150), [this]() {
this->clicked_button = -1;
this->SetDirty();
}};
/**
* Some data on this window has become invalid.

@ -20,6 +20,8 @@
#include "gfx_func.h"
#include "core/geometry_func.hpp"
#include "currency.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "zoom_func.h"
#include "widgets/graph_widget.h"
@ -892,7 +894,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
this->vscroll->SetCount(static_cast<int>(_sorted_standard_cargo_specs.size()));
/* Initialise the dataset */
this->OnHundredthTick();
this->UpdatePaymentRates();
this->FinishInitNested(window_number);
}
@ -1030,10 +1032,18 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
if (!gui_scope) return;
this->OnHundredthTick();
this->UpdatePaymentRates();
}
void OnHundredthTick() override
/** Update the payment rates on a regular interval. */
IntervalTimer<TimerWindow> update_payment_interval = {std::chrono::seconds(3), [this](auto) {
this->UpdatePaymentRates();
}};
/**
* Update the payment rates according to the latest information.
*/
void UpdatePaymentRates()
{
this->UpdateExcludedData();

@ -1,63 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file guitimer_func.h GUI Timers. */
#ifndef GUITIMER_FUNC_H
#define GUITIMER_FUNC_H
class GUITimer
{
protected:
uint timer;
uint interval;
public:
GUITimer() : timer(0), interval(0) { }
explicit GUITimer(uint interval) : timer(0), interval(interval) { }
inline bool HasElapsed() const
{
return this->interval == 0;
}
inline void SetInterval(uint interval)
{
this->timer = 0;
this->interval = interval;
}
/**
* Count how many times the interval has elapsed.
* Use to ensure a specific amount of events happen within a timeframe, e.g. for animation.
* @param delta Time since last test.
* @return Number of times the interval has elapsed.
*/
inline uint CountElapsed(uint delta)
{
if (this->interval == 0) return 0;
uint count = delta / this->interval;
if (this->timer + (delta % this->interval) >= this->interval) count++;
this->timer = (this->timer + delta) % this->interval;
return count;
}
/**
* Test if a timer has elapsed.
* Use to ensure an event happens only once within a timeframe, e.g. for window updates.
* @param delta Time since last test.
* @return True iff the timer has elapsed.
*/
inline bool Elapsed(uint delta)
{
if (this->CountElapsed(delta) == 0) return false;
this->SetInterval(0);
return true;
}
};
#endif /* GUITIMER_FUNC_H */

@ -42,6 +42,8 @@
#include "industry_cmd.h"
#include "querystring_gui.h"
#include "stringfilter_type.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "table/strings.h"
@ -723,8 +725,7 @@ public:
if (success && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
}
void OnHundredthTick() override
{
IntervalTimer<TimerWindow> update_interval = {std::chrono::seconds(3), [this](auto) {
if (_game_mode == GM_EDITOR) return;
if (this->count == 0) return;
const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
@ -739,7 +740,7 @@ public:
this->SetDirty();
}
}
}
}};
void OnTimeout() override
{
@ -1820,11 +1821,11 @@ public:
this->DrawWidgets();
}
void OnHundredthTick() override
{
/** Rebuild the industry list on a regular interval. */
IntervalTimer<TimerWindow> rebuild_interval = {std::chrono::seconds(3), [this](auto) {
this->industries.ForceResort();
this->BuildSortIndustriesList();
}
}};
/**
* Some data on this window has become invalid.

@ -30,10 +30,11 @@
#include "linkgraph/linkgraph_gui.h"
#include "tilehighlight_func.h"
#include "hotkeys.h"
#include "guitimer_func.h"
#include "error.h"
#include "news_gui.h"
#include "misc_cmd.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "saveload/saveload.h"
@ -209,12 +210,6 @@ enum {
struct MainWindow : Window
{
GUITimer refresh;
/* Refresh times in milliseconds */
static const uint LINKGRAPH_REFRESH_PERIOD = 7650;
static const uint LINKGRAPH_DELAY = 450;
MainWindow(WindowDesc *desc) : Window(desc)
{
this->InitNested(0);
@ -225,15 +220,12 @@ struct MainWindow : Window
nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZOOM_LVL_VIEWPORT));
this->viewport->overlay = std::make_shared<LinkGraphOverlay>(this, WID_M_VIEWPORT, 0, 0, 2);
this->refresh.SetInterval(LINKGRAPH_DELAY);
this->refresh_timeout.Reset();
}
void OnRealtimeTick(uint delta_ms) override
/** Refresh the link-graph overlay. */
void RefreshLinkGraph()
{
if (!this->refresh.Elapsed(delta_ms)) return;
this->refresh.SetInterval(LINKGRAPH_REFRESH_PERIOD);
if (this->viewport->overlay->GetCargoMask() == 0 ||
this->viewport->overlay->GetCompanyMask() == 0) {
return;
@ -243,6 +235,22 @@ struct MainWindow : Window
this->GetWidget<NWidgetBase>(WID_M_VIEWPORT)->SetDirty(this);
}
/** Refresh the link-graph overlay on a regular interval. */
IntervalTimer<TimerWindow> refresh_interval = {std::chrono::milliseconds(7650), [this](auto) {
RefreshLinkGraph();
}};
/**
* Sometimes when something happened, force an update to the link-graph a bit sooner.
*
* We don't do it instantly on those changes, as for example when you are scrolling,
* constantly refreshing the link-graph would be very slow. So we delay it a bit,
* and only draw it once the scrolling settles down.
*/
TimeoutTimer<TimerWindow> refresh_timeout = {std::chrono::milliseconds(450), [this]() {
RefreshLinkGraph();
}};
void OnPaint() override
{
this->DrawWidgets();
@ -416,7 +424,7 @@ struct MainWindow : Window
this->viewport->scrollpos_y += ScaleByZoom(delta.y, this->viewport->zoom);
this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;
this->refresh.SetInterval(LINKGRAPH_DELAY);
this->refresh_timeout.Reset();
}
void OnMouseWheel(int wheel) override
@ -431,7 +439,7 @@ struct MainWindow : Window
if (this->viewport != nullptr) {
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_M_VIEWPORT);
nvp->UpdateViewportCoordinates(this);
this->refresh.SetInterval(LINKGRAPH_DELAY);
this->refresh_timeout.Reset();
}
}

@ -24,10 +24,11 @@
#include "core/geometry_func.hpp"
#include "newgrf_debug.h"
#include "zoom_func.h"
#include "guitimer_func.h"
#include "viewport_func.h"
#include "landscape_cmd.h"
#include "rev.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/misc_widget.h"
@ -470,9 +471,6 @@ struct AboutWindow : public Window {
int line_height; ///< The height of a single line
static const int num_visible_lines = 19; ///< The number of lines visible simultaneously
static const uint TIMER_INTERVAL = 2100; ///< Scrolling interval, scaled by line text line height. This value chosen to maintain parity: 2100 / FONT_HEIGHT_NORMAL = 150ms
GUITimer timer;
AboutWindow() : Window(&_about_desc)
{
this->InitNested(WN_GAME_OPTIONS_ABOUT);
@ -500,10 +498,6 @@ struct AboutWindow : public Window {
d.width = std::max(d.width, GetStringBoundingBox(_credits[i]).width);
}
*size = maxdim(*size, d);
/* Set scroll interval based on required speed. To keep scrolling smooth,
* the interval is adjusted rather than the distance moved. */
this->timer.SetInterval(TIMER_INTERVAL / FONT_HEIGHT_NORMAL);
}
void DrawWidget(const Rect &r, int widget) const override
@ -521,18 +515,19 @@ struct AboutWindow : public Window {
}
}
void OnRealtimeTick(uint delta_ms) override
{
uint count = this->timer.CountElapsed(delta_ms);
if (count > 0) {
this->text_position -= count;
/* If the last text has scrolled start a new from the start */
if (this->text_position < (int)(this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y - lengthof(_credits) * this->line_height)) {
this->text_position = this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y + this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->current_y;
}
this->SetWidgetDirty(WID_A_SCROLLING_TEXT);
/**
* Scroll the text in the about window slow.
*
* The interval of 2100ms is chosen to maintain parity: 2100 / FONT_HEIGHT_NORMAL = 150ms.
*/
IntervalTimer<TimerWindow> scroll_interval = {std::chrono::milliseconds(2100) / FONT_HEIGHT_NORMAL, [this](uint count) {
this->text_position -= count;
/* If the last text has scrolled start a new from the start */
if (this->text_position < (int)(this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y - lengthof(_credits) * this->line_height)) {
this->text_position = this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->pos_y + this->GetWidget<NWidgetBase>(WID_A_SCROLLING_TEXT)->current_y;
}
}
this->SetWidgetDirty(WID_A_SCROLLING_TEXT);
}};
};
void ShowAboutWindow()

@ -18,6 +18,8 @@
#include "../toolbar_gui.h"
#include "../core/geometry_func.hpp"
#include "../zoom_func.h"
#include "../timer/timer.h"
#include "../timer/timer_window.h"
#include "network.h"
#include "network_client.h"
#include "network_base.h"
@ -170,9 +172,8 @@ void NetworkUndrawChatMessage()
}
}
/** Check if a message is expired. */
void NetworkChatMessageLoop()
{
/** Check if a message is expired on a regular interval. */
static IntervalTimer<TimerWindow> network_message_expired_interval(std::chrono::seconds(1), [](auto) {
auto now = std::chrono::steady_clock::now();
for (auto &cmsg : _chatmsg_list) {
/* Message has expired, remove from the list */
@ -182,7 +183,7 @@ void NetworkChatMessageLoop()
break;
}
}
}
});
/** Draw the chat message-box */
void NetworkDrawChatMessage()

@ -89,7 +89,6 @@ void NetworkInitChatMessage();
void NetworkReInitChatBoxSize();
void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message);
void NetworkUndrawChatMessage();
void NetworkChatMessageLoop();
void NetworkAfterNewGRFScan();

@ -32,11 +32,12 @@
#include "../core/geometry_func.hpp"
#include "../genworld.h"
#include "../map_type.h"
#include "../guitimer_func.h"
#include "../zoom_func.h"
#include "../sprite.h"
#include "../settings_internal.h"
#include "../company_cmd.h"
#include "../timer/timer.h"
#include "../timer/timer_window.h"
#include "../widgets/network_widget.h"
@ -55,8 +56,6 @@
static void ShowNetworkStartServerWindow();
static const int NETWORK_LIST_REFRESH_DELAY = 30; ///< Time, in seconds, between updates of the network list.
static ClientID _admin_client_id = INVALID_CLIENT_ID; ///< For what client a confirmation window is open.
static CompanyID _admin_company_id = INVALID_COMPANY; ///< For what company a confirmation window is open.
@ -229,7 +228,6 @@ protected:
Scrollbar *vscroll; ///< Vertical scrollbar of the list of servers.
QueryString name_editbox; ///< Client name editbox.
QueryString filter_editbox; ///< Editbox for filter on servers.
GUITimer requery_timer; ///< Timer for network requery.
bool searched_internet = false; ///< Did we ever press "Search Internet" button?
int lock_offset; ///< Left offset for lock icon.
@ -499,8 +497,6 @@ public:
this->last_joined = NetworkAddServer(_settings_client.network.last_joined, false);
this->server = this->last_joined;
this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000);
this->servers.SetListing(this->last_sorting);
this->servers.SetSortFuncs(this->sorter_funcs);
this->servers.SetFilterFuncs(this->filter_funcs);
@ -891,14 +887,12 @@ public:
this->vscroll->SetCapacityFromWidget(this, WID_NG_MATRIX);
}
void OnRealtimeTick(uint delta_ms) override
{
/** Refresh the online servers on a regular interval. */
IntervalTimer<TimerWindow> refresh_interval = {std::chrono::seconds(30), [this](uint count) {
if (!this->searched_internet) return;
if (!this->requery_timer.Elapsed(delta_ms)) return;
this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000);
_network_coordinator_client.GetListing();
}
}};
};
Listing NetworkGameWindow::last_sorting = {false, 5};

@ -28,7 +28,8 @@
#include "textfile_gui.h"
#include "tilehighlight_func.h"
#include "fios.h"
#include "guitimer_func.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/newgrf_widget.h"
#include "widgets/misc_widget.h"
@ -155,7 +156,6 @@ struct NewGRFParametersWindow : public Window {
bool clicked_increase; ///< True if the increase button was clicked, false for the decrease button.
bool clicked_dropdown; ///< Whether the dropdown is open.
bool closing_dropdown; ///< True, if the dropdown list is currently closing.
GUITimer timeout; ///< How long before we unpress the last-pressed button?
uint clicked_row; ///< The selected parameter
int line_height; ///< Height of a row in the matrix widget.
Scrollbar *vscroll;
@ -404,7 +404,7 @@ struct NewGRFParametersWindow : public Window {
par_info->SetValue(this->grf_config, val);
this->clicked_button = num;
this->timeout.SetInterval(150);
this->unclick_timeout.Reset();
}
} else if (par_info->type == PTYPE_UINT_ENUM && !par_info->complete_labels && click_count >= 2) {
/* Display a query box so users can enter a custom value. */
@ -484,13 +484,11 @@ struct NewGRFParametersWindow : public Window {
}
}
void OnRealtimeTick(uint delta_ms) override
{
if (timeout.Elapsed(delta_ms)) {
this->clicked_button = UINT_MAX;
this->SetDirty();
}
}
/** When reset, unclick the button after a small timeout. */
TimeoutTimer<TimerWindow> unclick_timeout = {std::chrono::milliseconds(150), [this]() {
this->clicked_button = UINT_MAX;
this->SetDirty();
}};
};
GRFParameterInfo NewGRFParametersWindow::dummy_parameter_info(0);

@ -32,10 +32,11 @@
#include "command_func.h"
#include "company_base.h"
#include "settings_internal.h"
#include "guitimer_func.h"
#include "group_gui.h"
#include "zoom_func.h"
#include "news_cmd.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/news_widget.h"
@ -267,9 +268,6 @@ struct NewsWindow : Window {
const NewsItem *ni; ///< News item to display.
static int duration; ///< Remaining time for showing the current news message (may only be access while a news item is displayed).
static const uint TIMER_INTERVAL = 210; ///< Scrolling interval, scaled by line text line height. This value chosen to maintain the 15ms at normal zoom.
GUITimer timer;
NewsWindow(WindowDesc *desc, const NewsItem *ni) : Window(desc), ni(ni)
{
NewsWindow::duration = 16650;
@ -322,11 +320,6 @@ struct NewsWindow : Window {
PositionNewsMessage(this);
}
void OnInit() override
{
this->timer.SetInterval(TIMER_INTERVAL / FONT_HEIGHT_NORMAL);
}
void DrawNewsBorder(const Rect &r) const
{
Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
@ -554,18 +547,21 @@ struct NewsWindow : Window {
void OnRealtimeTick(uint delta_ms) override
{
int count = this->timer.CountElapsed(delta_ms);
if (count > 0) {
/* Scroll up newsmessages from the bottom */
int newtop = std::max(this->top - 2 * count, _screen.height - this->height - this->status_height - this->chat_height);
this->SetWindowTop(newtop);
}
/* Decrement the news timer. We don't need to action an elapsed event here,
* so no need to use TimerElapsed(). */
if (NewsWindow::duration > 0) NewsWindow::duration -= delta_ms;
}
/**
* Scroll the news message slowly up from the bottom.
*
* The interval of 210ms is chosen to maintain 15ms at normal zoom: 210 / FONT_HEIGHT_NORMAL = 15ms.
*/
IntervalTimer<TimerWindow> scroll_interval = {std::chrono::milliseconds(210) / FONT_HEIGHT_NORMAL, [this](uint count) {
int newtop = std::max(this->top - 2 * static_cast<int>(count), _screen.height - this->height - this->status_height - this->chat_height);
this->SetWindowTop(newtop);
}};
private:
/**
* Moves the window to a new #top coordinate. Makes screen dirty where needed.

@ -21,6 +21,8 @@
#include "../hotkeys.h"
#include "../company_cmd.h"
#include "../misc_cmd.h"
#include "../timer/timer.h"
#include "../timer/timer_window.h"
#include "script_gui.h"
#include "script_log.hpp"
@ -288,7 +290,6 @@ struct ScriptSettingsWindow : public Window {
bool clicked_increase; ///< Whether we clicked the increase or decrease button.
bool clicked_dropdown; ///< Whether the dropdown is open.
bool closing_dropdown; ///< True, if the dropdown list is currently closing.
GUITimer timeout; ///< Timeout for unclicking the button.
int clicked_row; ///< The clicked row of settings.
int line_height; ///< Height of a row in the matrix widget.
Scrollbar *vscroll; ///< Cache of the vertical scrollbar.
@ -304,8 +305,7 @@ struct ScriptSettingsWindow : public Window {
slot(slot),
clicked_button(-1),
clicked_dropdown(false),
closing_dropdown(false),
timeout(0)
closing_dropdown(false)
{
this->script_config = GetConfig(slot);
@ -499,7 +499,7 @@ struct ScriptSettingsWindow : public Window {
if (new_val != old_val) {
this->script_config->SetSetting(config_item.name, new_val);
this->clicked_button = num;
this->timeout.SetInterval(150);
this->unclick_timeout.Reset();
}
} else if (!bool_item && !config_item.complete_labels) {
/* Display a query box so users can enter a custom value. */
@ -551,13 +551,11 @@ struct ScriptSettingsWindow : public Window {
this->vscroll->SetCapacityFromWidget(this, WID_SCRS_BACKGROUND);
}
void OnRealtimeTick(uint delta_ms) override
{
if (this->timeout.Elapsed(delta_ms)) {
this->clicked_button = -1;
this->SetDirty();
}
}
/** When reset, unclick the button after a small timeout. */
TimeoutTimer<TimerWindow> unclick_timeout = {std::chrono::milliseconds(150), [this]() {
this->clicked_button = -1;
this->SetDirty();
}};
/**
* Some data on this window has become invalid.

@ -27,6 +27,8 @@
#include "transparency.h"
#include "gui.h"
#include "signs_cmd.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/sign_widget.h"
@ -312,11 +314,11 @@ struct SignListWindow : Window, SignList {
this->SortSignsList();
}
void OnHundredthTick() override
{
/** Resort the sign listing on a regular interval. */
IntervalTimer<TimerWindow> rebuild_interval = {std::chrono::seconds(3), [this](auto) {
this->BuildSortSignList();
this->SetDirty();
}
}};
/**
* Some data on this window has become invalid.

@ -22,7 +22,6 @@
#include "sound_func.h"
#include "window_func.h"
#include "company_base.h"
#include "guitimer_func.h"
#include "zoom_func.h"
#include "smallmap_gui.h"
@ -1072,7 +1071,7 @@ void SmallMapWindow::SetupWidgetData()
this->GetWidget<NWidgetStacked>(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(plane);
}
SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(desc), refresh(GUITimer(FORCE_REFRESH_PERIOD))
SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(desc)
{
_smallmap_industry_highlight = INVALID_INDUSTRYTYPE;
this->overlay = new LinkGraphOverlay(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1);
@ -1416,7 +1415,6 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
}
if (new_highlight != _smallmap_industry_highlight) {
_smallmap_industry_highlight = new_highlight;
this->refresh.SetInterval(_smallmap_industry_highlight != INVALID_INDUSTRYTYPE ? BLINK_PERIOD : FORCE_REFRESH_PERIOD);
_smallmap_industry_highlight_state = true;
this->SetDirty();
}
@ -1588,11 +1586,9 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
}
}
/* virtual */ void SmallMapWindow::OnRealtimeTick(uint delta_ms)
/** Update all the links on the map. */
void SmallMapWindow::UpdateLinks()
{
/* Update the window every now and then */
if (!this->refresh.Elapsed(delta_ms)) return;
if (this->map_type == SMT_LINKSTATS) {
CompanyMask company_mask = this->GetOverlayCompanyMask();
if (this->overlay->GetCompanyMask() != company_mask) {
@ -1601,9 +1597,25 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
this->overlay->SetDirty();
}
}
}
/** Blink the industries (if hover over an industry). */
void SmallMapWindow::Blink()
{
if (_smallmap_industry_highlight == INVALID_INDUSTRYTYPE) return;
_smallmap_industry_highlight_state = !_smallmap_industry_highlight_state;
this->refresh.SetInterval(_smallmap_industry_highlight != INVALID_INDUSTRYTYPE ? BLINK_PERIOD : FORCE_REFRESH_PERIOD);
this->UpdateLinks();
this->SetDirty();
}
/** Force a full refresh of the map. */
void SmallMapWindow::ForceRefresh()
{
if (_smallmap_industry_highlight != INVALID_INDUSTRYTYPE) return;
this->UpdateLinks();
this->SetDirty();
}

@ -17,7 +17,8 @@
#include "blitter/factory.hpp"
#include "linkgraph/linkgraph_gui.h"
#include "widgets/smallmap_widget.h"
#include "guitimer_func.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
/* set up the cargos to be displayed in the smallmap's route legend */
void BuildLinkStatsLegend();
@ -74,8 +75,6 @@ protected:
static int map_height_limit; ///< Currently used/cached map height limit.
static const uint INDUSTRY_MIN_NUMBER_OF_COLUMNS = 2; ///< Minimal number of columns in the #WID_SM_LEGEND widget for the #SMT_INDUSTRY legend.
static const uint FORCE_REFRESH_PERIOD = 930; ///< map is redrawn after that many milliseconds.
static const uint BLINK_PERIOD = 450; ///< highlight blinking interval in milliseconds.
uint min_number_of_columns; ///< Minimal number of columns in legends.
uint min_number_of_fixed_rows; ///< Minimal number of rows in the legends for the fixed layouts only (all except #SMT_INDUSTRY).
@ -87,7 +86,6 @@ protected:
int32 subscroll; ///< Number of pixels (0..3) between the right end of the base tile and the pixel at the top-left corner of the smallmap display.
int zoom; ///< Zoom level. Bigger number means more zoom-out (further away).
GUITimer refresh; ///< Refresh timer.
LinkGraphOverlay *overlay;
static void BreakIndustryChainLink();
@ -156,6 +154,16 @@ protected:
return Company::IsValidID(_local_company) ? 1U << _local_company : MAX_UVALUE(CompanyMask);
}
/** Blink the industries (if selected) on a regular interval. */
IntervalTimer<TimerWindow> blink_interval = {std::chrono::milliseconds(450), [this](auto) {
Blink();
}};
/** Update the whole map on a regular interval. */
IntervalTimer<TimerWindow> refresh_interval = {std::chrono::milliseconds(930), [this](auto) {
ForceRefresh();
}};
void RebuildColourIndexIfNecessary();
uint GetNumberRowsLegend(uint columns) const;
void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item = 0);
@ -178,6 +186,10 @@ protected:
int GetPositionOnLegend(Point pt);
void UpdateLinks();
void Blink();
void ForceRefresh();
public:
friend class NWidgetSmallmapDisplay;
@ -196,7 +208,6 @@ public:
void OnInvalidateData(int data = 0, bool gui_scope = true) override;
bool OnRightClick(Point pt, int widget) override;
void OnMouseWheel(int wheel) override;
void OnRealtimeTick(uint delta_ms) override;
void OnScroll(Point delta) override;
void OnMouseOver(Point pt, int widget) override;
};

@ -25,8 +25,9 @@
#include "statusbar_gui.h"
#include "toolbar_gui.h"
#include "core/geometry_func.hpp"
#include "guitimer_func.h"
#include "zoom_func.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/statusbar_widget.h"
@ -78,19 +79,14 @@ static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left
struct StatusBarWindow : Window {
bool saving;
int ticker_scroll;
GUITimer ticker_timer;
GUITimer reminder_timeout;
static const int TICKER_STOP = 1640; ///< scrolling is finished when counter reaches this value
static const int REMINDER_START = 1350; ///< time in ms for reminder notification (red dot on the right) to stay
static const int REMINDER_STOP = 0; ///< reminder disappears when counter reaches this value
static const int COUNTER_STEP = 2; ///< this is subtracted from active counters every tick
static constexpr auto REMINDER_START = std::chrono::milliseconds(1350); ///< time in ms for reminder notification (red dot on the right) to stay
StatusBarWindow(WindowDesc *desc) : Window(desc)
{
this->ticker_scroll = TICKER_STOP;
this->ticker_timer.SetInterval(15);
this->reminder_timeout.SetInterval(REMINDER_STOP);
this->InitNested();
CLRBITS(this->flags, WF_WHITE_BORDER);
@ -186,7 +182,7 @@ struct StatusBarWindow : Window {
}
}
if (!this->reminder_timeout.HasElapsed()) {
if (!this->reminder_timeout.HasFired()) {
Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS);
DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, tr.right - icon_size.width, CenterBounds(r.top, r.bottom, icon_size.height));
}
@ -207,10 +203,10 @@ struct StatusBarWindow : Window {
case SBI_SAVELOAD_START: this->saving = true; break;
case SBI_SAVELOAD_FINISH: this->saving = false; break;
case SBI_SHOW_TICKER: this->ticker_scroll = 0; break;
case SBI_SHOW_REMINDER: this->reminder_timeout.SetInterval(REMINDER_START); break;
case SBI_SHOW_REMINDER: this->reminder_timeout.Reset(); break;
case SBI_NEWS_DELETED:
this->ticker_scroll = TICKER_STOP; // reset ticker ...
this->reminder_timeout.SetInterval(REMINDER_STOP); // ... and reminder
this->reminder_timeout.Abort(); // ... and reminder
break;
}
}
@ -224,23 +220,19 @@ struct StatusBarWindow : Window {
}
}
void OnRealtimeTick(uint delta_ms) override
{
/** Move information on the ticker slowly from one side to the other. */
IntervalTimer<TimerWindow> ticker_scroll_interval = {std::chrono::milliseconds(15), [this](uint count) {
if (_pause_mode != PM_UNPAUSED) return;
if (this->ticker_scroll < TICKER_STOP) { // Scrolling text
uint count = this->ticker_timer.CountElapsed(delta_ms);
if (count > 0) {
this->ticker_scroll += count;
this->SetWidgetDirty(WID_S_MIDDLE);
}
}
// Red blot to show there are new unread newsmessages
if (this->reminder_timeout.Elapsed(delta_ms)) {
if (this->ticker_scroll < TICKER_STOP) {
this->ticker_scroll += count;
this->SetWidgetDirty(WID_S_MIDDLE);
}
}
}};
TimeoutTimer<TimerWindow> reminder_timeout = {REMINDER_START, [this]() {
this->SetWidgetDirty(WID_S_MIDDLE);
}};
};
static const NWidgetPart _nested_main_status_widgets[] = {

@ -14,7 +14,9 @@
#include "core/smallvec_type.hpp"
#include "viewport_func.h"
#include "settings_type.h"
#include "guitimer_func.h"
#include "command_type.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "safeguards.h"
@ -91,11 +93,9 @@ void RemoveTextEffect(TextEffectID te_id)
_text_effects[te_id].Reset();
}
void MoveAllTextEffects(uint delta_ms)
{
static GUITimer texteffecttimer = GUITimer(MILLISECONDS_PER_TICK);
uint count = texteffecttimer.CountElapsed(delta_ms);
if (count == 0) return;
/** Slowly move text effects upwards. */
IntervalTimer<TimerWindow> move_all_text_effects_interval = {std::chrono::milliseconds(30), [](uint count) {
if (_pause_mode && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return;
for (TextEffect &te : _text_effects) {
if (te.string_id == INVALID_STRING_ID) continue;
@ -111,7 +111,7 @@ void MoveAllTextEffects(uint delta_ms)
te.top -= count * ZOOM_LVL_BASE;
te.MarkDirty(ZOOM_LVL_OUT_8X);
}
}
}};
void InitTextEffects()
{

@ -26,7 +26,6 @@ enum TextEffectMode {
typedef size_t TextEffectID;
void MoveAllTextEffects(uint delta_ms);
TextEffectID AddTextEffect(StringID msg, int x, int y, uint8 duration, TextEffectMode mode);
void InitTextEffects();
void DrawTextEffects(DrawPixelInfo *dpi);

@ -49,11 +49,12 @@
#include "story_base.h"
#include "toolbar_gui.h"
#include "framerate_type.h"
#include "guitimer_func.h"
#include "screenshot_gui.h"
#include "misc_cmd.h"
#include "league_gui.h"
#include "league_base.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/toolbar_widget.h"
@ -1992,8 +1993,6 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = {
/** Main toolbar. */
struct MainToolbarWindow : Window {
GUITimer timer;
MainToolbarWindow(WindowDesc *desc) : Window(desc)
{
this->InitNested(0);
@ -2004,8 +2003,6 @@ struct MainToolbarWindow : Window {
this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking); // if networking, disable fast-forward button
PositionMainToolbar(this);
DoZoomInOutWindow(ZOOM_NONE, this);
this->timer.SetInterval(MILLISECONDS_PER_TICK);
}
void FindWindowPlacementAndResize(int def_width, int def_height) override
@ -2109,11 +2106,8 @@ struct MainToolbarWindow : Window {
_last_started_action = CBF_NONE;
}
void OnRealtimeTick(uint delta_ms) override
{
if (!this->timer.Elapsed(delta_ms)) return;
this->timer.SetInterval(MILLISECONDS_PER_TICK);
/** Refresh the state of pause / game-speed on a regular interval.*/
IntervalTimer<TimerWindow> refresh_interval = {std::chrono::milliseconds(30), [this](auto) {
if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) {
this->ToggleWidgetLoweredState(WID_TN_PAUSE);
this->SetWidgetDirty(WID_TN_PAUSE);
@ -2123,7 +2117,7 @@ struct MainToolbarWindow : Window {
this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD);
this->SetWidgetDirty(WID_TN_FAST_FORWARD);
}
}
}};
void OnTimeout() override
{
@ -2353,8 +2347,6 @@ enum MainToolbarEditorHotkeys {
};
struct ScenarioEditorToolbarWindow : Window {
GUITimer timer;
ScenarioEditorToolbarWindow(WindowDesc *desc) : Window(desc)
{
this->InitNested(0);
@ -2363,8 +2355,6 @@ struct ScenarioEditorToolbarWindow : Window {
CLRBITS(this->flags, WF_WHITE_BORDER);
PositionMainToolbar(this);
DoZoomInOutWindow(ZOOM_NONE, this);
this->timer.SetInterval(MILLISECONDS_PER_TICK);
}
void FindWindowPlacementAndResize(int def_width, int def_height) override
@ -2495,11 +2485,8 @@ struct ScenarioEditorToolbarWindow : Window {
this->SetWidgetDirty(WID_TE_DATE_FORWARD);
}
void OnRealtimeTick(uint delta_ms) override
{
if (!this->timer.Elapsed(delta_ms)) return;
this->timer.SetInterval(MILLISECONDS_PER_TICK);
/** Refresh the state of pause / game-speed on a regular interval.*/
IntervalTimer<TimerWindow> refresh_interval = {std::chrono::milliseconds(30), [this](auto) {
if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) {
this->ToggleWidgetLoweredState(WID_TE_PAUSE);
this->SetDirty();
@ -2509,7 +2496,7 @@ struct ScenarioEditorToolbarWindow : Window {
this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD);
this->SetDirty();
}
}
}};
/**
* Some data on this window has become invalid.

@ -34,6 +34,8 @@
#include "widgets/dropdown_func.h"
#include "town_kdtree.h"
#include "town_cmd.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
#include "widgets/town_widget.h"
@ -307,10 +309,10 @@ public:
}
}
void OnHundredthTick() override
{
/** Redraw the whole window on a regular interval. */
IntervalTimer<TimerWindow> redraw_interval = {std::chrono::seconds(3), [this](auto) {
this->SetDirty();
}
}};
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
@ -966,11 +968,11 @@ public:
this->DrawWidgets();
}
void OnHundredthTick() override
{
/** Redraw the whole window on a regular interval. */
IntervalTimer<TimerWindow> rebuild_interval = {std::chrono::seconds(3), [this](auto) {
this->BuildSortTownList();
this->SetDirty();
}
}};
void OnResize() override
{

@ -12,8 +12,9 @@
#include "../string_func.h"
#include "../strings_func.h"
#include "../window_func.h"
#include "../guitimer_func.h"
#include "../zoom_func.h"
#include "../timer/timer.h"
#include "../timer/timer_window.h"
#include "dropdown_type.h"
#include "dropdown_widget.h"
@ -126,7 +127,6 @@ struct DropdownWindow : Window {
bool drag_mode;
bool instant_close; ///< Close the window when the mouse button is raised.
int scrolling; ///< If non-zero, auto-scroll the item list (one time).
GUITimer scrolling_timer; ///< Timer for auto-scroll of the item list.
Point position; ///< Position of the topleft corner of the window.
Scrollbar *vscroll;
@ -183,7 +183,6 @@ struct DropdownWindow : Window {
this->click_delay = 0;
this->drag_mode = true;
this->instant_close = instant_close;
this->scrolling_timer = GUITimer(MILLISECONDS_PER_TICK);
}
void Close() override
@ -278,22 +277,19 @@ struct DropdownWindow : Window {
}
}
void OnRealtimeTick(uint delta_ms) override
{
if (!this->scrolling_timer.Elapsed(delta_ms)) return;
this->scrolling_timer.SetInterval(MILLISECONDS_PER_TICK);
/** Rate limit how fast scrolling happens. */
IntervalTimer<TimerWindow> scroll_interval = {std::chrono::milliseconds(30), [this](auto) {
if (this->scrolling == 0) return;
if (this->scrolling != 0) {
int pos = this->vscroll->GetPosition();
int pos = this->vscroll->GetPosition();
this->vscroll->UpdatePosition(this->scrolling);
this->scrolling = 0;
this->vscroll->UpdatePosition(this->scrolling);
this->scrolling = 0;
if (pos != this->vscroll->GetPosition()) {
this->SetDirty();
}
if (pos != this->vscroll->GetPosition()) {
this->SetDirty();
}
}
}};
void OnMouseLoop() override
{

@ -37,7 +37,6 @@
#include "video/video_driver.hpp"
#include "framerate_type.h"
#include "network/network_func.h"
#include "guitimer_func.h"
#include "news_func.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
@ -1888,14 +1887,9 @@ void ResetWindowSystem()
static void DecreaseWindowCounters()
{
static byte hundredth_tick_timeout = 100;
if (_scroller_click_timeout != 0) _scroller_click_timeout--;
if (hundredth_tick_timeout != 0) hundredth_tick_timeout--;
for (Window *w : Window::Iterate()) {
if (!_network_dedicated && hundredth_tick_timeout == 0) w->OnHundredthTick();
if (_scroller_click_timeout == 0) {
/* Unclick scrollbar buttons if they are pressed. */
for (uint i = 0; i < w->nested_array_size; i++) {
@ -1927,8 +1921,6 @@ static void DecreaseWindowCounters()
w->RaiseButtons(true);
}
}
if (hundredth_tick_timeout == 0) hundredth_tick_timeout = 100;
}
static void HandlePlacePresize()
@ -3111,20 +3103,21 @@ static IntervalTimer<TimerWindow> white_border_interval(std::chrono::millisecond
*/
void UpdateWindows()
{
static std::chrono::steady_clock::time_point last_time = std::chrono::steady_clock::now();
uint delta_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - last_time).count();
static auto last_time = std::chrono::steady_clock::now();
auto now = std::chrono::steady_clock::now();
auto delta_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_time);
if (delta_ms == 0) return;
if (delta_ms.count() == 0) return;
last_time = std::chrono::steady_clock::now();
last_time = now;
PerformanceMeasurer framerate(PFE_DRAWING);
PerformanceAccumulator::Reset(PFE_DRAWWORLD);
ProcessPendingPerformanceMeasurements();
TimerManager<TimerWindow>::Elapsed(std::chrono::milliseconds(delta_ms));
CallWindowRealtimeTickEvent(delta_ms);
TimerManager<TimerWindow>::Elapsed(delta_ms);
CallWindowRealtimeTickEvent(delta_ms.count());
/* Process invalidations before anything else. */
for (Window *w : Window::Iterate()) {
@ -3132,8 +3125,6 @@ void UpdateWindows()
w->ProcessHighlightedInvalidations();
}
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;

@ -621,13 +621,6 @@ public:
*/
virtual void OnGameTick() {}
/**
* Called once every 100 (game) ticks, or once every 3s, whichever comes last.
* In normal game speed the frequency is 1 call every 100 ticks (can be more than 3s).
* In fast-forward the frequency is 1 call every ~3s (can be more than 100 ticks).
*/
virtual void OnHundredthTick() {}
/**
* Called periodically.
*/

Loading…
Cancel
Save