Codechange: create a type for the "free_data" of NewsItems and (de)allocate it with new and delete

pull/332/head
rubidium42 3 years ago committed by rubidium42
parent df601b8559
commit aa9818db90

@ -376,7 +376,7 @@ set_name:;
MarkWholeScreenDirty(); MarkWholeScreenDirty();
if (c->is_ai) { if (c->is_ai) {
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1); CompanyNewsInformation *cni = new CompanyNewsInformation();
cni->FillData(c); cni->FillData(c);
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE); SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION); SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
@ -888,7 +888,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
/* Delete any open window of the company */ /* Delete any open window of the company */
CloseCompanyWindows(c->index); CloseCompanyWindows(c->index);
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1); CompanyNewsInformation *cni = new CompanyNewsInformation();
cni->FillData(c); cni->FillData(c);
/* Show the bankrupt news */ /* Show the bankrupt news */

@ -580,7 +580,7 @@ static void CompanyCheckBankrupt(Company *c)
/* Warn about bankruptcy after 3 months */ /* Warn about bankruptcy after 3 months */
case 4: { case 4: {
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1); CompanyNewsInformation *cni = new CompanyNewsInformation();
cni->FillData(c); cni->FillData(c);
SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE); SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE);
SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION); SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION);
@ -1975,7 +1975,7 @@ static void DoAcquireCompany(Company *c)
{ {
CompanyID ci = c->index; CompanyID ci = c->index;
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1); CompanyNewsInformation *cni = new CompanyNewsInformation();
cni->FillData(c, Company::Get(_current_company)); cni->FillData(c, Company::Get(_current_company));
SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE); SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE);

@ -15,7 +15,7 @@
#include "station_type.h" #include "station_type.h"
#include "industry_type.h" #include "industry_type.h"
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32 ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32 ref2 = UINT32_MAX, void *free_data = nullptr); void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32 ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32 ref2 = UINT32_MAX, const NewsAllocatedData *data = nullptr);
static inline void AddCompanyNewsItem(StringID string, CompanyNewsInformation *cni) static inline void AddCompanyNewsItem(StringID string, CompanyNewsInformation *cni)
{ {
@ -42,9 +42,9 @@ static inline void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle)
AddNewsItem(string, NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle); AddNewsItem(string, NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle);
} }
static inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, void *free_data = nullptr, StationID station = INVALID_STATION) static inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, const NewsAllocatedData *data = nullptr, StationID station = INVALID_STATION)
{ {
AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_TILE, tile, station == INVALID_STATION ? NR_NONE : NR_STATION, station, free_data); AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_TILE, tile, station == INVALID_STATION ? NR_NONE : NR_STATION, station, data);
} }
static inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID industry) static inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID industry)

@ -355,7 +355,7 @@ struct NewsWindow : Window {
break; break;
case WID_N_MGR_NAME: case WID_N_MGR_NAME:
SetDParamStr(0, static_cast<const CompanyNewsInformation *>(this->ni->free_data)->president_name); SetDParamStr(0, static_cast<const CompanyNewsInformation *>(this->ni->data)->president_name);
str = STR_JUST_RAW_STRING; str = STR_JUST_RAW_STRING;
break; break;
@ -433,13 +433,13 @@ struct NewsWindow : Window {
break; break;
case WID_N_MGR_FACE: { case WID_N_MGR_FACE: {
const CompanyNewsInformation *cni = (const CompanyNewsInformation*)this->ni->free_data; const CompanyNewsInformation *cni = static_cast<const CompanyNewsInformation*>(this->ni->data);
DrawCompanyManagerFace(cni->face, cni->colour, r.left, r.top); DrawCompanyManagerFace(cni->face, cni->colour, r.left, r.top);
GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR); GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
break; break;
} }
case WID_N_MGR_NAME: { case WID_N_MGR_NAME: {
const CompanyNewsInformation *cni = (const CompanyNewsInformation*)this->ni->free_data; const CompanyNewsInformation *cni = static_cast<const CompanyNewsInformation*>(this->ni->data);
SetDParamStr(0, cni->president_name); SetDParamStr(0, cni->president_name);
DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER); DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
break; break;
@ -783,7 +783,7 @@ static void DeleteNewsItem(NewsItem *ni)
* *
* @see NewsSubtype * @see NewsSubtype
*/ */
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32 ref1, NewsReferenceType reftype2, uint32 ref2, void *free_data) void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32 ref1, NewsReferenceType reftype2, uint32 ref2, const NewsAllocatedData *data)
{ {
if (_game_mode == GM_MENU) return; if (_game_mode == GM_MENU) return;
@ -801,7 +801,7 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy
ni->reftype2 = reftype2; ni->reftype2 = reftype2;
ni->ref1 = ref1; ni->ref1 = ref1;
ni->ref2 = ref2; ni->ref2 = ref2;
ni->free_data = free_data; ni->data = data;
ni->date = _date; ni->date = _date;
CopyOutDParam(ni->params, 0, lengthof(ni->params)); CopyOutDParam(ni->params, 0, lengthof(ni->params));
@ -882,8 +882,8 @@ CommandCost CmdCustomNewsItem(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
if (company != INVALID_OWNER && company != _local_company) return CommandCost(); if (company != INVALID_OWNER && company != _local_company) return CommandCost();
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
char *news = stredup(text.c_str()); NewsStringData *news = new NewsStringData(text);
SetDParamStr(0, news); SetDParamStr(0, news->string);
AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, p2, NR_NONE, UINT32_MAX, news); AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, p2, NR_NONE, UINT32_MAX, news);
} }

@ -115,6 +115,12 @@ struct NewsTypeData {
NewsDisplay GetDisplay() const; NewsDisplay GetDisplay() const;
}; };
/** Container for any custom data that must be deleted after the news item has reached end-of-life. */
struct NewsAllocatedData {
virtual ~NewsAllocatedData() {}
};
/** Information about a single item of news. */ /** Information about a single item of news. */
struct NewsItem { struct NewsItem {
NewsItem *prev; ///< Previous news item NewsItem *prev; ///< Previous news item
@ -129,23 +135,29 @@ struct NewsItem {
uint32 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. uint32 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.
uint32 ref2; ///< Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted. uint32 ref2; ///< Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted.
void *free_data; ///< Data to be freed when the news item has reached its end. const NewsAllocatedData *data; ///< Custom data for the news item that have to be deallocated (deleted) when the news item has reached its end.
~NewsItem() ~NewsItem()
{ {
free(this->free_data); delete this->data;
} }
uint64 params[10]; ///< Parameters for string resolving. uint64 params[10]; ///< Parameters for string resolving.
}; };
/** Container for a single string to be passed as NewsAllocatedData. */
struct NewsStringData : NewsAllocatedData {
std::string string; ///< The string to retain.
NewsStringData(const std::string &str) : string(str) {}
};
/** /**
* Data that needs to be stored for company news messages. * Data that needs to be stored for company news messages.
* The problem with company news messages are the custom name * The problem with company news messages are the custom name
* of the companies and the fact that the company data is reset, * of the companies and the fact that the company data is reset,
* resulting in wrong names and such. * resulting in wrong names and such.
*/ */
struct CompanyNewsInformation { struct CompanyNewsInformation : NewsAllocatedData {
char company_name[64]; ///< The name of the company char company_name[64]; ///< The name of the company
char president_name[64]; ///< The name of the president char president_name[64]; ///< The name of the president
char other_company_name[64]; ///< The name of the company taking over this one char other_company_name[64]; ///< The name of the company taking over this one

@ -43,22 +43,19 @@ void Subsidy::AwardTo(CompanyID company)
this->awarded = company; this->awarded = company;
this->remaining = _settings_game.difficulty.subsidy_duration * MONTHS_IN_YEAR; this->remaining = _settings_game.difficulty.subsidy_duration * MONTHS_IN_YEAR;
char company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
SetDParam(0, company); SetDParam(0, company);
GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
char *cn = stredup(company_name);
/* Add a news item */ /* Add a news item */
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(this, SubsidyDecodeParamType::NewsAwarded); std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(this, SubsidyDecodeParamType::NewsAwarded);
InjectDParam(1); InjectDParam(1);
SetDParamStr(0, cn); SetDParamStr(0, company_name->string);
AddNewsItem( AddNewsItem(
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier, STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier,
NT_SUBSIDIES, NF_NORMAL, NT_SUBSIDIES, NF_NORMAL,
reftype.first, this->src, reftype.second, this->dst, reftype.first, this->src, reftype.second, this->dst,
cn company_name
); );
AI::BroadcastNewEvent(new ScriptEventSubsidyAwarded(this->index)); AI::BroadcastNewEvent(new ScriptEventSubsidyAwarded(this->index));
Game::NewEvent(new ScriptEventSubsidyAwarded(this->index)); Game::NewEvent(new ScriptEventSubsidyAwarded(this->index));

@ -2020,15 +2020,13 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
SetDParam(0, t->index); SetDParam(0, t->index);
AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile); AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile);
} else { } else {
char company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
SetDParam(0, _current_company); SetDParam(0, _current_company);
GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
char *cn = stredup(company_name); SetDParamStr(0, company_name->string);
SetDParamStr(0, cn);
SetDParam(1, t->index); SetDParam(1, t->index);
AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile, cn); AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile, company_name);
} }
AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index)); AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
Game::NewEvent(new ScriptEventTownFounded(t->index)); Game::NewEvent(new ScriptEventTownFounded(t->index));
@ -3090,15 +3088,13 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags)
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
t->road_build_months = 6; t->road_build_months = 6;
char company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
SetDParam(0, _current_company); SetDParam(0, _current_company);
GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
char *cn = stredup(company_name);
SetDParam(0, t->index); SetDParam(0, t->index);
SetDParamStr(1, cn); SetDParamStr(1, company_name->string);
AddNewsItem(STR_NEWS_ROAD_REBUILDING, NT_GENERAL, NF_NORMAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cn); AddNewsItem(STR_NEWS_ROAD_REBUILDING, NT_GENERAL, NF_NORMAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, company_name);
AI::BroadcastNewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); AI::BroadcastNewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
Game::NewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); Game::NewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
} }
@ -3235,7 +3231,7 @@ static CommandCost TownActionBuyRights(Town *t, DoCommandFlag flags)
SetWindowClassesDirty(WC_STATION_VIEW); SetWindowClassesDirty(WC_STATION_VIEW);
/* Spawn news message */ /* Spawn news message */
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1); CompanyNewsInformation *cni = new CompanyNewsInformation();
cni->FillData(Company::Get(_current_company)); cni->FillData(Company::Get(_current_company));
SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE); SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE);
SetDParam(1, STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION); SetDParam(1, STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION);

Loading…
Cancel
Save