Changeset - r27389:34c6b4cd5a75
[Not reviewed]
master
0 4 0
Peter Nelson - 13 months ago 2023-05-18 11:19:51
peter1138@openttd.org
Codechange: Use std::optional for GRF Parameter list.
4 files changed with 63 insertions and 66 deletions:
0 comments (0 inline, 0 general)
src/newgrf.cpp
Show inline comments
 
@@ -8416,16 +8416,16 @@ static bool HandleParameterInfo(ByteRead
 
			continue;
 
		}
 

	
 
		if (id >= _cur.grfconfig->param_info.size()) {
 
			_cur.grfconfig->param_info.resize(id + 1);
 
		}
 
		if (_cur.grfconfig->param_info[id] == nullptr) {
 
			_cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
 
		}
 
		_cur_parameter = _cur.grfconfig->param_info[id];
 
		if (!_cur.grfconfig->param_info[id].has_value()) {
 
			_cur.grfconfig->param_info[id] = GRFParameterInfo(id);
 
		}
 
		_cur_parameter = &_cur.grfconfig->param_info[id].value();
 
		/* Read all parameter-data and process each node. */
 
		if (!HandleNodes(buf, _tags_parameters)) return false;
 
		type = buf->ReadByte();
 
	}
 
	return true;
 
}
src/newgrf_config.cpp
Show inline comments
 
@@ -55,30 +55,18 @@ GRFConfig::GRFConfig(const GRFConfig &co
 
	flags(config.flags & ~(1 << GCF_COPY)),
 
	status(config.status),
 
	grf_bugs(config.grf_bugs),
 
	num_params(config.num_params),
 
	num_valid_params(config.num_valid_params),
 
	palette(config.palette),
 
	param_info(config.param_info),
 
	has_param_defaults(config.has_param_defaults)
 
{
 
	MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
 
	MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
 
	if (config.error != nullptr) this->error = std::make_unique<GRFError>(*config.error);
 
	for (uint i = 0; i < config.param_info.size(); i++) {
 
		if (config.param_info[i] == nullptr) {
 
			this->param_info.push_back(nullptr);
 
		} else {
 
			this->param_info.push_back(new GRFParameterInfo(*config.param_info[i]));
 
		}
 
	}
 
}
 

	
 
/** Cleanup a GRFConfig object. */
 
GRFConfig::~GRFConfig()
 
{
 
	for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i];
 
}
 

	
 
/**
 
 * Copy the parameter information from the \a src config.
 
 * @param src Source config.
 
 */
 
@@ -124,13 +112,13 @@ void GRFConfig::SetParameterDefaults()
 
	this->num_params = 0;
 
	MemSetT<uint32>(this->param, 0, lengthof(this->param));
 

	
 
	if (!this->has_param_defaults) return;
 

	
 
	for (uint i = 0; i < this->param_info.size(); i++) {
 
		if (this->param_info[i] == nullptr) continue;
 
		if (!this->param_info[i]) continue;
 
		this->param_info[i]->SetValue(this, this->param_info[i]->def_value);
 
	}
 
}
 

	
 
/**
 
 * Set the palette of this GRFConfig to something suitable.
 
@@ -150,14 +138,14 @@ void GRFConfig::SetSuitablePalette()
 

	
 
/**
 
 * Finalize Action 14 info after file scan is finished.
 
 */
 
void GRFConfig::FinalizeParameterInfo()
 
{
 
	for (GRFParameterInfo *info : this->param_info) {
 
		if (info == nullptr) continue;
 
	for (auto &info : this->param_info) {
 
		if (!info.has_value()) continue;
 
		info->Finalize();
 
	}
 
}
 

	
 
GRFConfig *_all_grfs;
 
GRFConfig *_grfconfig;
 
@@ -524,20 +512,14 @@ compatible_grf:
 
				c->name = f->name;
 
				c->info = f->name;
 
				c->error = nullptr;
 
				c->version = f->version;
 
				c->min_loadable_version = f->min_loadable_version;
 
				c->num_valid_params = f->num_valid_params;
 
				c->param_info = f->param_info;
 
				c->has_param_defaults = f->has_param_defaults;
 
				for (uint i = 0; i < f->param_info.size(); i++) {
 
					if (f->param_info[i] == nullptr) {
 
						c->param_info.push_back(nullptr);
 
					} else {
 
						c->param_info.push_back(new GRFParameterInfo(*f->param_info[i]));
 
					}
 
				}
 
			}
 
		}
 
	}
 

	
 
	return res;
 
}
src/newgrf_config.h
Show inline comments
 
@@ -150,13 +150,12 @@ struct GRFParameterInfo {
 
};
 

	
 
/** Information about GRF, used in the game and (part of it) in savegames */
 
struct GRFConfig : ZeroedMemoryAllocator {
 
	GRFConfig(const std::string &filename = std::string{});
 
	GRFConfig(const GRFConfig &config);
 
	~GRFConfig();
 

	
 
	/* Remove the copy assignment, as the default implementation will not do the right thing. */
 
	GRFConfig &operator=(GRFConfig &rhs) = delete;
 

	
 
	GRFIdentifier ident;                        ///< grfid and md5sum to uniquely identify newgrfs
 
	uint8 original_md5sum[16];                  ///< MD5 checksum of original file if only a 'compatible' file was loaded
 
@@ -172,13 +171,13 @@ struct GRFConfig : ZeroedMemoryAllocator
 
	GRFStatus status;                           ///< NOSAVE: GRFStatus, enum
 
	uint32 grf_bugs;                            ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
 
	uint32 param[0x80];                         ///< GRF parameters
 
	uint8 num_params;                           ///< Number of used parameters
 
	uint8 num_valid_params;                     ///< NOSAVE: Number of valid parameters (action 0x14)
 
	uint8 palette;                              ///< GRFPalette, bitset
 
	std::vector<GRFParameterInfo *> param_info; ///< NOSAVE: extra information about the parameters
 
	std::vector<std::optional<GRFParameterInfo>> param_info; ///< NOSAVE: extra information about the parameters
 
	bool has_param_defaults;                    ///< NOSAVE: did this newgrf specify any defaults for it's parameters
 

	
 
	struct GRFConfig *next;                     ///< NOSAVE: Next item in the linked list
 

	
 
	void CopyParams(const GRFConfig &src);
 

	
src/newgrf_gui.cpp
Show inline comments
 
@@ -184,16 +184,37 @@ struct NewGRFParametersWindow : public W
 

	
 
	/**
 
	 * Get a dummy parameter-info object with default information.
 
	 * @param nr The param number that should be changed.
 
	 * @return GRFParameterInfo with dummy information about the given parameter.
 
	 */
 
	static GRFParameterInfo *GetDummyParameterInfo(uint nr)
 
	static GRFParameterInfo &GetDummyParameterInfo(uint nr)
 
	{
 
		dummy_parameter_info.param_nr = nr;
 
		return &dummy_parameter_info;
 
		return dummy_parameter_info;
 
	}
 

	
 
	/**
 
	 * Test if GRF Parameter Info exists for a given parameter index.
 
	 * @param nr The param number that should be tested.
 
	 * @return True iff the parameter info exists.
 
	 */
 
	bool HasParameterInfo(uint nr) const
 
	{
 
		return nr < this->grf_config->param_info.size() && this->grf_config->param_info[nr].has_value();
 
	}
 

	
 
	/**
 
	 * Get GRF Parameter Info exists for a given parameter index.
 
	 * If the parameter info does not exist, a dummy parameter-info is returned instead.
 
	 * @param nr The param number that should be got.
 
	 * @return Reference to the GRFParameterInfo.
 
	 */
 
	GRFParameterInfo &GetParameterInfo(uint nr) const
 
	{
 
		return this->HasParameterInfo(nr) ? this->grf_config->param_info[nr].value() : GetDummyParameterInfo(nr);
 
	}
 

	
 
	void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
 
	{
 
		switch (widget) {
 
			case WID_NP_NUMPAR_DEC:
 
@@ -220,15 +241,14 @@ struct NewGRFParametersWindow : public W
 
				size->height = 5 * this->line_height;
 
				break;
 

	
 
			case WID_NP_DESCRIPTION:
 
				/* Minimum size of 4 lines. The 500 is the default size of the window. */
 
				Dimension suggestion = {500U - WidgetDimensions::scaled.frametext.Horizontal(), (uint)FONT_HEIGHT_NORMAL * 4 + WidgetDimensions::scaled.frametext.Vertical()};
 
				for (uint i = 0; i < this->grf_config->param_info.size(); i++) {
 
					const GRFParameterInfo *par_info = this->grf_config->param_info[i];
 
					if (par_info == nullptr) continue;
 
				for (const auto &par_info : this->grf_config->param_info) {
 
					if (!par_info.has_value()) continue;
 
					const char *desc = GetGRFStringFromGRFText(par_info->desc);
 
					if (desc == nullptr) continue;
 
					Dimension d = GetStringMultiLineBoundingBox(desc, suggestion);
 
					d.height += WidgetDimensions::scaled.frametext.Vertical();
 
					suggestion = maxdim(d, suggestion);
 
				}
 
@@ -246,15 +266,15 @@ struct NewGRFParametersWindow : public W
 
		}
 
	}
 

	
 
	void DrawWidget(const Rect &r, int widget) const override
 
	{
 
		if (widget == WID_NP_DESCRIPTION) {
 
			const GRFParameterInfo *par_info = (this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr;
 
			if (par_info == nullptr) return;
 
			const char *desc = GetGRFStringFromGRFText(par_info->desc);
 
			if (!this->HasParameterInfo(this->clicked_row)) return;
 
			const GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
 
			const char *desc = GetGRFStringFromGRFText(par_info.desc);
 
			if (desc == nullptr) return;
 
			DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), desc, TC_BLACK);
 
			return;
 
		} else if (widget != WID_NP_BACKGROUND) {
 
			return;
 
		}
 
@@ -264,39 +284,38 @@ struct NewGRFParametersWindow : public W
 
		uint buttons_left = rtl ? ir.right - SETTING_BUTTON_WIDTH : ir.left;
 
		Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl);
 

	
 
		int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
 
		int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
 
		for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
 
			GRFParameterInfo *par_info = (i < this->grf_config->param_info.size()) ? this->grf_config->param_info[i] : nullptr;
 
			if (par_info == nullptr) par_info = GetDummyParameterInfo(i);
 
			uint32 current_value = par_info->GetValue(this->grf_config);
 
			GRFParameterInfo &par_info = this->GetParameterInfo(i);
 
			uint32 current_value = par_info.GetValue(this->grf_config);
 
			bool selected = (i == this->clicked_row);
 

	
 
			if (par_info->type == PTYPE_BOOL) {
 
			if (par_info.type == PTYPE_BOOL) {
 
				DrawBoolButton(buttons_left, ir.top + button_y_offset, current_value != 0, this->editable);
 
				SetDParam(2, par_info->GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
 
			} else if (par_info->type == PTYPE_UINT_ENUM) {
 
				if (par_info->complete_labels) {
 
				SetDParam(2, par_info.GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
 
			} else if (par_info.type == PTYPE_UINT_ENUM) {
 
				if (par_info.complete_labels) {
 
					DrawDropDownButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable);
 
				} else {
 
					DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value);
 
					DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info.min_value, this->editable && current_value < par_info.max_value);
 
				}
 
				SetDParam(2, STR_JUST_INT);
 
				SetDParam(3, current_value);
 
				auto it = par_info->value_names.find(current_value);
 
				if (it != par_info->value_names.end()) {
 
				auto it = par_info.value_names.find(current_value);
 
				if (it != par_info.value_names.end()) {
 
					const char *label = GetGRFStringFromGRFText(it->second);
 
					if (label != nullptr) {
 
						SetDParam(2, STR_JUST_RAW_STRING);
 
						SetDParamStr(3, label);
 
					}
 
				}
 
			}
 

	
 
			const char *name = GetGRFStringFromGRFText(par_info->name);
 
			const char *name = GetGRFStringFromGRFText(par_info.name);
 
			if (name != nullptr) {
 
				SetDParam(0, STR_JUST_RAW_STRING);
 
				SetDParamStr(1, name);
 
			} else {
 
				SetDParam(0, STR_NEWGRF_PARAMETERS_DEFAULT_NAME);
 
				SetDParam(1, i + 1);
 
@@ -351,18 +370,17 @@ struct NewGRFParametersWindow : public W
 
				}
 

	
 
				Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, RectPadding::zero);
 
				int x = pt.x - r.left;
 
				if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
 

	
 
				GRFParameterInfo *par_info = *it;
 
				if (par_info == nullptr) par_info = GetDummyParameterInfo(num);
 
				GRFParameterInfo &par_info = it->has_value() ? it->value() : GetDummyParameterInfo(num);
 

	
 
				/* One of the arrows is clicked */
 
				uint32 old_val = par_info->GetValue(this->grf_config);
 
				if (par_info->type != PTYPE_BOOL && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && par_info->complete_labels) {
 
				uint32 old_val = par_info.GetValue(this->grf_config);
 
				if (par_info.type != PTYPE_BOOL && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && par_info.complete_labels) {
 
					if (this->clicked_dropdown) {
 
						/* unclick the dropdown */
 
						HideDropDownMenu(this);
 
						this->clicked_dropdown = false;
 
						this->closing_dropdown = false;
 
					} else {
 
@@ -377,41 +395,41 @@ struct NewGRFParametersWindow : public W
 
						/* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
 
						if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
 
							this->clicked_dropdown = true;
 
							this->closing_dropdown = false;
 

	
 
							DropDownList list;
 
							for (uint32 i = par_info->min_value; i <= par_info->max_value; i++) {
 
								list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.find(i)->second), i, false));
 
							for (uint32 i = par_info.min_value; i <= par_info.max_value; i++) {
 
								list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false));
 
							}
 

	
 
							ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE);
 
						}
 
					}
 
				} else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
 
					uint32 val = old_val;
 
					if (par_info->type == PTYPE_BOOL) {
 
					if (par_info.type == PTYPE_BOOL) {
 
						val = !val;
 
					} else {
 
						if (x >= SETTING_BUTTON_WIDTH / 2) {
 
							/* Increase button clicked */
 
							if (val < par_info->max_value) val++;
 
							if (val < par_info.max_value) val++;
 
							this->clicked_increase = true;
 
						} else {
 
							/* Decrease button clicked */
 
							if (val > par_info->min_value) val--;
 
							if (val > par_info.min_value) val--;
 
							this->clicked_increase = false;
 
						}
 
					}
 
					if (val != old_val) {
 
						par_info->SetValue(this->grf_config, val);
 
						par_info.SetValue(this->grf_config, val);
 

	
 
						this->clicked_button = num;
 
						this->unclick_timeout.Reset();
 
					}
 
				} else if (par_info->type == PTYPE_UINT_ENUM && !par_info->complete_labels && click_count >= 2) {
 
				} 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. */
 
					SetDParam(0, old_val);
 
					ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
 
				}
 
				this->SetDirty();
 
				break;
 
@@ -431,25 +449,23 @@ struct NewGRFParametersWindow : public W
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		if (StrEmpty(str)) return;
 
		int32 value = atoi(str);
 
		GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr;
 
		if (par_info == nullptr) par_info = GetDummyParameterInfo(this->clicked_row);
 
		uint32 val = Clamp<uint32>(value, par_info->min_value, par_info->max_value);
 
		par_info->SetValue(this->grf_config, val);
 
		GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
 
		uint32 val = Clamp<uint32>(value, par_info.min_value, par_info.max_value);
 
		par_info.SetValue(this->grf_config, val);
 
		this->SetDirty();
 
	}
 

	
 
	void OnDropdownSelect(int widget, int index) override
 
	{
 
		assert(this->clicked_dropdown);
 
		GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr;
 
		if (par_info == nullptr) par_info = GetDummyParameterInfo(this->clicked_row);
 
		par_info->SetValue(this->grf_config, index);
 
		GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
 
		par_info.SetValue(this->grf_config, index);
 
		this->SetDirty();
 
	}
 

	
 
	void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override
 
	{
 
		/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
0 comments (0 inline, 0 general)