Fix #12459, f6a88e4: Crashes when deleting news messages. (#12460)

The updated logic in f6a88e4 for deleting news messages did things in the wrong order.
This commit is contained in:
Peter Nelson 2024-04-09 21:46:29 +01:00 committed by GitHub
parent 2976a46d06
commit 90ca3515da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 27 additions and 15 deletions

View File

@ -685,13 +685,14 @@ static bool ReadyForNextNewsItem()
/** Move to the next ticker item */ /** Move to the next ticker item */
static void MoveToNextTickerItem() static void MoveToNextTickerItem()
{ {
assert(!std::empty(_news));
/* There is no status bar, so no reason to show news; /* There is no status bar, so no reason to show news;
* especially important with the end game screen when * especially important with the end game screen when
* there is no status bar but possible news. */ * there is no status bar but possible news. */
if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return; if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
/* No news to move to. */
if (std::empty(_news)) return;
/* if we're not at the latest item, then move on */ /* if we're not at the latest item, then move on */
while (_statusbar_news != std::begin(_news)) { while (_statusbar_news != std::begin(_news)) {
--_statusbar_news; --_statusbar_news;
@ -719,8 +720,6 @@ static void MoveToNextTickerItem()
/** Move to the next news item */ /** Move to the next news item */
static void MoveToNextNewsItem() static void MoveToNextNewsItem()
{ {
assert(!std::empty(_news));
/* There is no status bar, so no reason to show news; /* There is no status bar, so no reason to show news;
* especially important with the end game screen when * especially important with the end game screen when
* there is no status bar but possible news. */ * there is no status bar but possible news. */
@ -729,6 +728,9 @@ static void MoveToNextNewsItem()
CloseWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown CloseWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown
_forced_news = std::end(_news); _forced_news = std::end(_news);
/* No news to move to. */
if (std::empty(_news)) return;
/* if we're not at the latest item, then move on */ /* if we're not at the latest item, then move on */
while (_current_news != std::begin(_news)) { while (_current_news != std::begin(_news)) {
--_current_news; --_current_news;
@ -755,28 +757,38 @@ static void MoveToNextNewsItem()
/** Delete a news item from the queue */ /** Delete a news item from the queue */
static std::list<NewsItem>::iterator DeleteNewsItem(std::list<NewsItem>::iterator ni) static std::list<NewsItem>::iterator DeleteNewsItem(std::list<NewsItem>::iterator ni)
{ {
if (_forced_news == ni || _current_news == ni) { bool updateCurrentNews = (_forced_news == ni || _current_news == ni);
/* When we're the current news, go to the previous item first; bool updateStatusbarNews = (_statusbar_news == ni);
* we just possibly made that the last news item. */
if (_current_news == ni) _current_news = (_current_news == std::begin(_news)) ? std::end(_news) : std::prev(_current_news);
if (updateCurrentNews) {
/* When we're the current news, go to the next older item first;
* we just possibly made that the last news item. */
if (_current_news == ni) ++_current_news;
if (_forced_news == ni) _forced_news = std::end(_news);
}
if (updateStatusbarNews) {
/* When we're the current news, go to the next older item first;
* we just possibly made that the last news item. */
++_statusbar_news;
}
/* Delete the news from the news queue. */
ni = _news.erase(ni);
if (updateCurrentNews) {
/* About to remove the currently forced item (shown as newspapers) || /* About to remove the currently forced item (shown as newspapers) ||
* about to remove the currently displayed item (newspapers) */ * about to remove the currently displayed item (newspapers) */
MoveToNextNewsItem(); MoveToNextNewsItem();
} }
if (_statusbar_news == ni) { if (updateStatusbarNews) {
/* When we're the current news, go to the previous item first;
* we just possibly made that the last news item. */
if (_statusbar_news == ni) _statusbar_news = (_statusbar_news == std::begin(_news)) ? std::end(_news) : std::prev(_statusbar_news);
/* About to remove the currently displayed item (ticker, or just a reminder) */ /* About to remove the currently displayed item (ticker, or just a reminder) */
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar
MoveToNextTickerItem(); MoveToNextTickerItem();
} }
/* Delete the news from the news queue. */ return ni;
return _news.erase(ni);
} }
/** /**