Changeset - r27211:94f8f534745e
[Not reviewed]
master
0 5 0
Rubidium - 17 months ago 2023-04-27 17:03:03
rubidium@openttd.org
Codechange: use std::string instead of stredup/free for goals
5 files changed with 27 insertions and 38 deletions:
0 comments (0 inline, 0 general)
src/goal.cpp
Show inline comments
 
@@ -75,26 +75,25 @@ std::tuple<CommandCost, GoalID> CmdCreat
 
			if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return { CMD_ERROR, INVALID_GOAL };
 
			break;
 
		}
 

	
 
		default: return { CMD_ERROR, INVALID_GOAL };
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		Goal *g = new Goal();
 
		g->type = type;
 
		g->dst = dest;
 
		g->company = company;
 
		g->text = stredup(text.c_str());
 
		g->progress = nullptr;
 
		g->text = text;
 
		g->completed = false;
 

	
 
		if (g->company == INVALID_COMPANY) {
 
			InvalidateWindowClassesData(WC_GOALS_LIST);
 
		} else {
 
			InvalidateWindowData(WC_GOALS_LIST, g->company);
 
		}
 
		if (Goal::GetNumItems() == 1) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
 

	
 
		return { CommandCost(), g->index };
 
	}
 

	
 
@@ -134,26 +133,25 @@ CommandCost CmdRemoveGoal(DoCommandFlag 
 
 * @param goal GoalID to update.
 
 * @param text Text of the goal.
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdSetGoalText(DoCommandFlag flags, GoalID goal, const std::string &text)
 
{
 
	if (_current_company != OWNER_DEITY) return CMD_ERROR;
 
	if (!Goal::IsValidID(goal)) return CMD_ERROR;
 
	if (text.empty()) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		Goal *g = Goal::Get(goal);
 
		free(g->text);
 
		g->text = stredup(text.c_str());
 
		g->text = text;
 

	
 
		if (g->company == INVALID_COMPANY) {
 
			InvalidateWindowClassesData(WC_GOALS_LIST);
 
		} else {
 
			InvalidateWindowData(WC_GOALS_LIST, g->company);
 
		}
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
@@ -161,30 +159,25 @@ CommandCost CmdSetGoalText(DoCommandFlag
 
 * @param flags type of operation
 
 * @param goal GoalID to update.
 
 * @param text Progress text of the goal.
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdSetGoalProgress(DoCommandFlag flags, GoalID goal, const std::string &text)
 
{
 
	if (_current_company != OWNER_DEITY) return CMD_ERROR;
 
	if (!Goal::IsValidID(goal)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		Goal *g = Goal::Get(goal);
 
		free(g->progress);
 
		if (text.empty()) {
 
			g->progress = nullptr;
 
		} else {
 
			g->progress = stredup(text.c_str());
 
		}
 
		g->progress = text;
 

	
 
		if (g->company == INVALID_COMPANY) {
 
			InvalidateWindowClassesData(WC_GOALS_LIST);
 
		} else {
 
			InvalidateWindowData(WC_GOALS_LIST, g->company);
 
		}
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
@@ -246,25 +239,25 @@ CommandCost CmdGoalQuestion(DoCommandFla
 
	}
 
	uint min_buttons = (type == GQT_QUESTION ? 1 : 0);
 
	if (CountBits(button_mask) < min_buttons || CountBits(button_mask) > 3) return CMD_ERROR;
 
	if (type >= GQT_END) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		if (is_client) {
 
			if (client != _network_own_client_id) return CommandCost();
 
		} else {
 
			if (company == INVALID_COMPANY && !Company::IsValidID(_local_company)) return CommandCost();
 
			if (company != INVALID_COMPANY && company != _local_company) return CommandCost();
 
		}
 
		ShowGoalQuestion(uniqueid, type, button_mask, text.c_str());
 
		ShowGoalQuestion(uniqueid, type, button_mask, text);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Reply to a goal question.
 
 * @param flags type of operation
 
 * @param uniqueid Unique ID to use for this question.
 
 * @param button Button the company pressed
 
 * @return the cost of this operation or an error
 
 */
src/goal_base.h
Show inline comments
 
@@ -10,31 +10,31 @@
 
#ifndef GOAL_BASE_H
 
#define GOAL_BASE_H
 

	
 
#include "company_type.h"
 
#include "goal_type.h"
 
#include "core/pool_type.hpp"
 

	
 
typedef Pool<Goal, GoalID, 64, 64000> GoalPool;
 
extern GoalPool _goal_pool;
 

	
 
/** Struct about goals, current and completed */
 
struct Goal : GoalPool::PoolItem<&_goal_pool> {
 
	CompanyID company; ///< Goal is for a specific company; INVALID_COMPANY if it is global
 
	GoalType type;     ///< Type of the goal
 
	GoalTypeID dst;    ///< Index of type
 
	char *text;        ///< Text of the goal.
 
	char *progress;    ///< Progress text of the goal.
 
	bool completed;    ///< Is the goal completed or not?
 
	CompanyID company;    ///< Goal is for a specific company; INVALID_COMPANY if it is global
 
	GoalType type;        ///< Type of the goal
 
	GoalTypeID dst;       ///< Index of type
 
	std::string text;     ///< Text of the goal.
 
	std::string progress; ///< Progress text of the goal.
 
	bool completed;       ///< Is the goal completed or not?
 

	
 
	/**
 
	 * We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
 
	 */
 
	inline Goal() { }
 

	
 
	/**
 
	 * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter
 
	 */
 
	inline ~Goal() { free(this->text); free(this->progress); }
 
	inline ~Goal() { }
 
};
 

	
 
#endif /* GOAL_BASE_H */
src/goal_gui.cpp
Show inline comments
 
@@ -203,25 +203,25 @@ struct GoalListWindow : public Window {
 
			if (s->company == this->window_number) {
 
				if (IsInsideMM(pos, 0, cap)) {
 
					switch (column) {
 
						case GC_GOAL: {
 
							/* Display the goal. */
 
							SetDParamStr(0, s->text);
 
							uint width_reduction = progress_col_width > 0 ? progress_col_width + WidgetDimensions::scaled.framerect.Horizontal() : 0;
 
							DrawString(r.Indent(width_reduction, !rtl), STR_GOALS_TEXT);
 
							break;
 
						}
 

	
 
						case GC_PROGRESS:
 
							if (s->progress != nullptr) {
 
							if (!s->progress.empty()) {
 
								SetDParamStr(0, s->progress);
 
								StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS;
 
								DrawString(r.WithWidth(progress_col_width, !rtl), str, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
 
							}
 
							break;
 
					}
 
					r.top += FONT_HEIGHT_NORMAL;
 
				}
 
				pos++;
 
				num++;
 
			}
 
		}
 
@@ -233,25 +233,25 @@ struct GoalListWindow : public Window {
 
		}
 
	}
 

	
 
	void OnPaint() override
 
	{
 
		this->DrawWidgets();
 

	
 
		if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
 

	
 
		/* Calculate progress column width. */
 
		uint max_width = 0;
 
		for (const Goal *s : Goal::Iterate()) {
 
			if (s->progress != nullptr) {
 
			if (!s->progress.empty()) {
 
				SetDParamStr(0, s->progress);
 
				StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS;
 
				uint str_width = GetStringBoundingBox(str).width;
 
				if (str_width > max_width) max_width = str_width;
 
			}
 
		}
 

	
 
		NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_GOAL_LIST);
 
		uint progress_col_width = std::min(max_width, wid->current_x);
 

	
 
		/* Draw goal list. */
 
		this->DrawListColumn(GC_PROGRESS, wid, progress_col_width);
 
@@ -313,58 +313,54 @@ static WindowDesc _goals_list_desc(
 
 * Open a goal list window.
 
 * @param company %Company to display the goals for, use #INVALID_COMPANY to display global goals.
 
 */
 
void ShowGoalsList(CompanyID company)
 
{
 
	if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
 

	
 
	AllocateWindowDescFront<GoalListWindow>(&_goals_list_desc, company);
 
}
 

	
 
/** Ask a question about a goal. */
 
struct GoalQuestionWindow : public Window {
 
	char *question;     ///< Question to ask (private copy).
 
	int buttons;        ///< Number of valid buttons in #button.
 
	int button[3];      ///< Buttons to display.
 
	TextColour colour;  ///< Colour of the question text.
 
	std::string question; ///< Question to ask (private copy).
 
	int buttons;          ///< Number of valid buttons in #button.
 
	int button[3];        ///< Buttons to display.
 
	TextColour colour;    ///< Colour of the question text.
 

	
 
	GoalQuestionWindow(WindowDesc *desc, WindowNumber window_number, TextColour colour, uint32 button_mask, const char *question) : Window(desc), colour(colour)
 
	GoalQuestionWindow(WindowDesc *desc, WindowNumber window_number, TextColour colour, uint32 button_mask, const std::string &question) : Window(desc), colour(colour)
 
	{
 
		this->question = stredup(question);
 
		this->question = question;
 

	
 
		/* Figure out which buttons we have to enable. */
 
		int n = 0;
 
		for (uint bit : SetBitIterator(button_mask)) {
 
			if (bit >= GOAL_QUESTION_BUTTON_COUNT) break;
 
			this->button[n++] = bit;
 
			if (n == 3) break;
 
		}
 
		this->buttons = n;
 
		assert(this->buttons < 4);
 

	
 
		this->CreateNestedTree();
 
		if (this->buttons == 0) {
 
			this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(SZSP_HORIZONTAL);
 
			this->GetWidget<NWidgetStacked>(WID_GQ_BUTTON_SPACER)->SetDisplayedPlane(SZSP_HORIZONTAL);
 
		} else {
 
			this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(this->buttons - 1);
 
			this->GetWidget<NWidgetStacked>(WID_GQ_BUTTON_SPACER)->SetDisplayedPlane(0);
 
		}
 
		this->FinishInitNested(window_number);
 
	}
 

	
 
	~GoalQuestionWindow()
 
	{
 
		free(this->question);
 
	}
 

	
 
	void SetStringParameters(int widget) const override
 
	{
 
		switch (widget) {
 
			case WID_GQ_BUTTON_1:
 
				SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[0]);
 
				break;
 

	
 
			case WID_GQ_BUTTON_2:
 
				SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[1]);
 
				break;
 

	
 
@@ -545,17 +541,17 @@ static WindowDesc _goal_question_list_de
 
		WDF_CONSTRUCTION,
 
		_nested_goal_question_widgets_error, lengthof(_nested_goal_question_widgets_error),
 
	},
 
};
 

	
 
/**
 
 * Display a goal question.
 
 * @param id Window number to use.
 
 * @param type Type of question.
 
 * @param button_mask Buttons to display.
 
 * @param question Question to ask.
 
 */
 
void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question)
 
void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const std::string &question)
 
{
 
	assert(type < GQT_END);
 
	new GoalQuestionWindow(&_goal_question_list_desc[type], id, type == 3 ? TC_WHITE : TC_BLACK, button_mask, question);
 
}
src/gui.h
Show inline comments
 
@@ -40,25 +40,25 @@ Window *ShowBuildAirToolbar();
 
void ShowGenerateLandscape();
 
void ShowHeightmapLoad();
 

	
 
/* misc_gui.cpp */
 
void ShowLandInfo(TileIndex tile);
 
void ShowAboutWindow();
 
void ShowBuildTreesToolbar();
 
void ShowTownDirectory();
 
void ShowIndustryDirectory();
 
void ShowIndustryCargoesWindow();
 
void ShowSubsidiesList();
 
void ShowGoalsList(CompanyID company);
 
void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question);
 
void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const std::string &question);
 
void ShowStoryBook(CompanyID company, uint16 page_id = INVALID_STORY_PAGE);
 

	
 
void ShowEstimatedCostOrIncome(Money cost, int x, int y);
 

	
 
void ShowExtraViewportWindow(TileIndex tile = INVALID_TILE);
 
void ShowExtraViewportWindowForTileUnderCursor();
 

	
 
/* bridge_gui.cpp */
 
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type);
 

	
 
void ShowBuildIndustryWindow();
 
void ShowFoundTownWindow();
src/saveload/goal_sl.cpp
Show inline comments
 
@@ -8,30 +8,30 @@
 
/** @file goal_sl.cpp Code handling saving and loading of goals */
 

	
 
#include "../stdafx.h"
 

	
 
#include "saveload.h"
 
#include "compat/goal_sl_compat.h"
 

	
 
#include "../goal_base.h"
 

	
 
#include "../safeguards.h"
 

	
 
static const SaveLoad _goals_desc[] = {
 
	    SLE_VAR(Goal, company,   SLE_FILE_U16 | SLE_VAR_U8),
 
	    SLE_VAR(Goal, type,      SLE_FILE_U16 | SLE_VAR_U8),
 
	    SLE_VAR(Goal, dst,       SLE_UINT32),
 
	    SLE_STR(Goal, text,      SLE_STR | SLF_ALLOW_CONTROL, 0),
 
	SLE_CONDSTR(Goal, progress,  SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION),
 
	SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
 
	     SLE_VAR(Goal, company,   SLE_FILE_U16 | SLE_VAR_U8),
 
	     SLE_VAR(Goal, type,      SLE_FILE_U16 | SLE_VAR_U8),
 
	     SLE_VAR(Goal, dst,       SLE_UINT32),
 
	    SLE_SSTR(Goal, text,      SLE_STR | SLF_ALLOW_CONTROL),
 
	SLE_CONDSSTR(Goal, progress,  SLE_STR | SLF_ALLOW_CONTROL, SLV_182, SL_MAX_VERSION),
 
	 SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
 
};
 

	
 
struct GOALChunkHandler : ChunkHandler {
 
	GOALChunkHandler() : ChunkHandler('GOAL', CH_TABLE) {}
 

	
 
	void Save() const override
 
	{
 
		SlTableHeader(_goals_desc);
 

	
 
		for (Goal *s : Goal::Iterate()) {
 
			SlSetArrayIndex(s->index);
 
			SlObject(s, _goals_desc);
0 comments (0 inline, 0 general)