Changeset - r24121:31fdede83ab2
[Not reviewed]
master
0 1 0
Charles Pigott - 5 years ago 2020-02-16 22:03:12
charlespigott@googlemail.com
Change: Keep News Window usable by only storing the 1024 latest news messages
1 file changed with 50 insertions and 44 deletions:
0 comments (0 inline, 0 general)
src/news_gui.cpp
Show inline comments
 
@@ -35,24 +35,25 @@
 
#include "guitimer_func.h"
 
#include "group_gui.h"
 

	
 
#include "widgets/news_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
const NewsItem *_statusbar_news_item = nullptr;
 

	
 
static uint MIN_NEWS_AMOUNT = 30;        ///< preferred minimum amount of news messages
 
static uint MAX_NEWS_AMOUNT = 1 << 10;   ///< Do not exceed this number of news messages
 
static uint _total_news = 0;             ///< current number of news items
 
static NewsItem *_oldest_news = nullptr; ///< head of news items queue
 
NewsItem *_latest_news = nullptr;        ///< tail of news items queue
 

	
 
/**
 
 * Forced news item.
 
 * Users can force an item by accessing the history or "last message".
 
 * If the message being shown was forced by the user, a pointer is stored
 
 * in _forced_news. Otherwise, \a _forced_news variable is nullptr.
 
 */
 
static const NewsItem *_forced_news = nullptr;
 

	
 
@@ -720,24 +721,68 @@ static void MoveToNextNewsItem()
 

	
 
			case ND_SUMMARY: // Summary - show ticker, skipped here
 
				continue;
 

	
 
			case ND_FULL: // Full - show newspaper
 
				ShowNewspaper(ni);
 
				break;
 
		}
 
		return;
 
	}
 
}
 

	
 
/** Delete a news item from the queue */
 
static void DeleteNewsItem(NewsItem *ni)
 
{
 
	/* Delete the news from the news queue. */
 
	if (ni->prev != nullptr) {
 
		ni->prev->next = ni->next;
 
	} else {
 
		assert(_oldest_news == ni);
 
		_oldest_news = ni->next;
 
	}
 

	
 
	if (ni->next != nullptr) {
 
		ni->next->prev = ni->prev;
 
	} else {
 
		assert(_latest_news == ni);
 
		_latest_news = ni->prev;
 
	}
 

	
 
	_total_news--;
 

	
 
	if (_forced_news == ni || _current_news == ni) {
 
		/* When we're the current news, go to the previous item first;
 
		 * we just possibly made that the last news item. */
 
		if (_current_news == ni) _current_news = ni->prev;
 

	
 
		/* About to remove the currently forced item (shown as newspapers) ||
 
		 * about to remove the currently displayed item (newspapers) */
 
		MoveToNextNewsItem();
 
	}
 

	
 
	if (_statusbar_news_item == ni) {
 
		/* When we're the current news, go to the previous item first;
 
		 * we just possibly made that the last news item. */
 
		_statusbar_news_item = ni->prev;
 

	
 
		/* About to remove the currently displayed item (ticker, or just a reminder) */
 
		MoveToNextTickerItem();
 
	}
 

	
 
	delete ni;
 

	
 
	SetWindowDirty(WC_MESSAGE_HISTORY, 0);
 
}
 

	
 
/**
 
 * Add a new newsitem to be shown.
 
 * @param string String to display
 
 * @param type news category
 
 * @param flags display flags for the news
 
 * @param reftype1 Type of ref1
 
 * @param ref1     Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleting the news when the object is deleted.
 
 * @param reftype2 Type of ref2
 
 * @param ref2     Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted.
 
 * @param free_data Pointer to data that must be freed once the news message is cleared
 
 *
 
 * @see NewsSubtype
 
@@ -768,24 +813,29 @@ void AddNewsItem(StringID string, NewsTy
 
		assert(_oldest_news == nullptr);
 
		_oldest_news = ni;
 
		ni->prev = nullptr;
 
	} else {
 
		assert(_latest_news->next == nullptr);
 
		_latest_news->next = ni;
 
		ni->prev = _latest_news;
 
	}
 

	
 
	ni->next = nullptr;
 
	_latest_news = ni;
 

	
 
	/* Keep the number of stored news items to a managable number */
 
	if (_total_news > MAX_NEWS_AMOUNT) {
 
		DeleteNewsItem(_oldest_news);
 
	}
 

	
 
	SetWindowDirty(WC_MESSAGE_HISTORY, 0);
 
}
 

	
 
/**
 
 * Create a new custom news item.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 various bitstuffed elements
 
 * - p1 = (bit  0 -  7) - NewsType of the message.
 
 * - p1 = (bit  8 - 15) - NewsReferenceType of first reference.
 
 * - p1 = (bit 16 - 23) - Company this news message is for.
 
 * @param p2 First reference of the news message.
 
@@ -835,68 +885,24 @@ CommandCost CmdCustomNewsItem(TileIndex 
 

	
 
	if (company != INVALID_OWNER && company != _local_company) return CommandCost();
 

	
 
	if (flags & DC_EXEC) {
 
		char *news = stredup(text);
 
		SetDParamStr(0, news);
 
		AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, p2, NR_NONE, UINT32_MAX, news);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/** Delete a news item from the queue */
 
static void DeleteNewsItem(NewsItem *ni)
 
{
 
	/* Delete the news from the news queue. */
 
	if (ni->prev != nullptr) {
 
		ni->prev->next = ni->next;
 
	} else {
 
		assert(_oldest_news == ni);
 
		_oldest_news = ni->next;
 
	}
 

	
 
	if (ni->next != nullptr) {
 
		ni->next->prev = ni->prev;
 
	} else {
 
		assert(_latest_news == ni);
 
		_latest_news = ni->prev;
 
	}
 

	
 
	_total_news--;
 

	
 
	if (_forced_news == ni || _current_news == ni) {
 
		/* When we're the current news, go to the previous item first;
 
		 * we just possibly made that the last news item. */
 
		if (_current_news == ni) _current_news = ni->prev;
 

	
 
		/* About to remove the currently forced item (shown as newspapers) ||
 
		 * about to remove the currently displayed item (newspapers) */
 
		MoveToNextNewsItem();
 
	}
 

	
 
	if (_statusbar_news_item == ni) {
 
		/* When we're the current news, go to the previous item first;
 
		 * we just possibly made that the last news item. */
 
		_statusbar_news_item = ni->prev;
 

	
 
		/* About to remove the currently displayed item (ticker, or just a reminder) */
 
		MoveToNextTickerItem();
 
	}
 

	
 
	delete ni;
 

	
 
	SetWindowDirty(WC_MESSAGE_HISTORY, 0);
 
}
 

	
 
/**
 
 * Delete a news item type about a vehicle.
 
 * When the news item type is INVALID_STRING_ID all news about the vehicle gets deleted.
 
 * @param vid  The vehicle to remove the news for.
 
 * @param news The news type to remove.
 
 */
 
void DeleteVehicleNews(VehicleID vid, StringID news)
 
{
 
	NewsItem *ni = _oldest_news;
 

	
 
	while (ni != nullptr) {
 
		NewsItem *next = ni->next;
0 comments (0 inline, 0 general)