changeset 17413:74d340e6542d draft

(svn r22162) -Fix [FS#4533]: No update of NewGRF window when unknown GRF name becomes available
author yexo <yexo@openttd.org>
date Thu, 03 Mar 2011 18:47:46 +0000
parents 7fac37e42782
children 1b0094757e18
files src/network/network_gamelist.cpp src/network/network_udp.cpp src/newgrf.cpp src/newgrf_config.cpp src/newgrf_config.h
diffstat 5 files changed, 81 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/network/network_gamelist.cpp
+++ b/src/network/network_gamelist.cpp
@@ -182,17 +182,22 @@
 				/* Don't know the GRF, so mark game incompatible and the (possibly)
 				 * already resolved name for this GRF (another server has sent the
 				 * name of the GRF already */
-				AddGRFTextToList(&c->name, FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true));
+				c->name->Release();
+				c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true);
+				c->name->AddRef();
 				c->status = GCS_NOT_FOUND;
 
 				/* If we miss a file, we're obviously incompatible */
 				item->info.compatible = false;
 			} else {
-				c->filename  = f->filename;
-				CleanUpGRFText(c->name);
-				c->name      = DuplicateGRFText(f->name);
-				c->info      = f->info;
-				c->status    = GCS_UNKNOWN;
+				c->filename = f->filename;
+				c->name->Release();
+				c->name = f->name;
+				c->name->AddRef();
+				c->info->Release();
+				c->info = f->info;
+				c->info->AddRef();
+				c->status = GCS_UNKNOWN;
 			}
 		}
 	}
--- a/src/network/network_udp.cpp
+++ b/src/network/network_udp.cpp
@@ -369,7 +369,6 @@
 	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
 
 	for (i = 0; i < num_grfs; i++) {
-		char *unknown_name;
 		char name[NETWORK_GRF_NAME_LENGTH];
 		GRFIdentifier c;
 
@@ -380,12 +379,12 @@
 		 * and causes problems when showing the NewGRF list. */
 		if (StrEmpty(name)) continue;
 
-		/* Finds the fake GRFConfig for the just read GRF ID and MD5sum tuple.
+		/* Try to find the GRFTextWrapper for the name of this GRF ID and MD5sum tuple.
 		 * If it exists and not resolved yet, then name of the fake GRF is
 		 * overwritten with the name from the reply. */
-		unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
-		if (unknown_name != NULL && strcmp(unknown_name, UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
-			ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
+		GRFTextWrapper *unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
+		if (unknown_name != NULL && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
+			AddGRFTextToList(&unknown_name->text, name);
 		}
 	}
 }
@@ -398,12 +397,18 @@
 		/* Don't know the GRF, so mark game incompatible and the (possibly)
 		 * already resolved name for this GRF (another server has sent the
 		 * name of the GRF already */
-		AddGRFTextToList(&config->name, FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true));
+		config->name->Release();
+		config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true);
+		config->name->AddRef();
 		config->status = GCS_NOT_FOUND;
 	} else {
-		config->filename  = f->filename;
-		config->name      = DuplicateGRFText(f->name);
-		config->info      = f->info;
+		config->filename = f->filename;
+		config->name->Release();
+		config->name = f->name;
+		config->name->AddRef();
+		config->info->Release();
+		config->info = f->info;
+		config->info->AddRef();
 	}
 	SetBit(config->flags, GCF_COPY);
 }
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -5382,11 +5382,11 @@
 	/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
 	if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
 
-	AddGRFTextToList(&_cur_grfconfig->name, 0x7F, grfid, name);
+	AddGRFTextToList(&_cur_grfconfig->name->text, 0x7F, grfid, name);
 
 	if (buf->HasData()) {
 		const char *info = buf->ReadString();
-		AddGRFTextToList(&_cur_grfconfig->info, 0x7F, grfid, info);
+		AddGRFTextToList(&_cur_grfconfig->info->text, 0x7F, grfid, info);
 	}
 
 	/* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
@@ -6466,14 +6466,14 @@
 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
 static bool ChangeGRFName(byte langid, const char *str)
 {
-	AddGRFTextToList(&_cur_grfconfig->name, langid, _cur_grfconfig->ident.grfid, str);
+	AddGRFTextToList(&_cur_grfconfig->name->text, langid, _cur_grfconfig->ident.grfid, str);
 	return true;
 }
 
 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
 static bool ChangeGRFDescription(byte langid, const char *str)
 {
-	AddGRFTextToList(&_cur_grfconfig->info, langid, _cur_grfconfig->ident.grfid, str);
+	AddGRFTextToList(&_cur_grfconfig->info->text, langid, _cur_grfconfig->ident.grfid, str);
 	return true;
 }
 
--- a/src/newgrf_config.cpp
+++ b/src/newgrf_config.cpp
@@ -21,15 +21,31 @@
 #include "fileio_func.h"
 #include "fios.h"
 
+/** Create a new GRFTextWrapper. */
+GRFTextWrapper::GRFTextWrapper() :
+	text(NULL)
+{
+}
+
+/** Cleanup a GRFTextWrapper object. */
+GRFTextWrapper::~GRFTextWrapper()
+{
+	CleanUpGRFText(this->text);
+}
+
 /**
  * Create a new GRFConfig.
  * @param filename Set the filename of this GRFConfig to filename. The argument
  *   is copied so the original string isn't needed after the constructor.
  */
 GRFConfig::GRFConfig(const char *filename) :
+	name(new GRFTextWrapper()),
+	info(new GRFTextWrapper()),
 	num_valid_params(lengthof(param))
 {
 	if (filename != NULL) this->filename = strdup(filename);
+	this->name->AddRef();
+	this->info->AddRef();
 }
 
 /**
@@ -39,6 +55,8 @@
 GRFConfig::GRFConfig(const GRFConfig &config) :
 	ZeroedMemoryAllocator(),
 	ident(config.ident),
+	name(config.name),
+	info(config.info),
 	version(config.version),
 	min_loadable_version(config.min_loadable_version),
 	flags(config.flags & ~(1 << GCF_COPY)),
@@ -52,8 +70,8 @@
 	MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
 	MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
 	if (config.filename != NULL) this->filename = strdup(config.filename);
-	this->name = DuplicateGRFText(config.name);
-	this->info = DuplicateGRFText(config.info);
+	this->name->AddRef();
+	this->info->AddRef();
 	if (config.error    != NULL) this->error    = new GRFError(*config.error);
 	for (uint i = 0; i < config.param_info.Length(); i++) {
 		if (config.param_info[i] == NULL) {
@@ -67,13 +85,13 @@
 /** Cleanup a GRFConfig object. */
 GRFConfig::~GRFConfig()
 {
-	/* GCF_COPY as in NOT strdupped/alloced the filename and info */
+	/* GCF_COPY as in NOT strdupped/alloced the filename */
 	if (!HasBit(this->flags, GCF_COPY)) {
 		free(this->filename);
-		CleanUpGRFText(this->info);
 		delete this->error;
 	}
-	CleanUpGRFText(this->name);
+	this->name->Release();
+	this->info->Release();
 
 	for (uint i = 0; i < this->param_info.Length(); i++) delete this->param_info[i];
 }
@@ -85,7 +103,7 @@
  */
 const char *GRFConfig::GetName() const
 {
-	const char *name = GetGRFStringFromGRFText(this->name);
+	const char *name = GetGRFStringFromGRFText(this->name->text);
 	return StrEmpty(name) ? this->filename : name;
 }
 
@@ -95,7 +113,7 @@
  */
 const char *GRFConfig::GetDescription() const
 {
-	return GetGRFStringFromGRFText(this->info);
+	return GetGRFStringFromGRFText(this->info->text);
 }
 
 /** Set the default value for all parameters as specified by action14. */
@@ -482,8 +500,12 @@
 				free(c->filename);
 				c->filename = strdup(f->filename);
 				memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum));
-				if (c->name == NULL) c->name = DuplicateGRFText(f->name);
-				if (c->info == NULL) c->info = DuplicateGRFText(f->info);
+				c->name->Release();
+				c->name = f->name;
+				c->name->AddRef();
+				c->info->Release();
+				c->info = f->name;
+				c->info->AddRef();
 				c->error = NULL;
 				c->version = f->version;
 				c->min_loadable_version = f->min_loadable_version;
@@ -646,7 +668,7 @@
 /** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */
 struct UnknownGRF : public GRFIdentifier {
 	UnknownGRF *next;
-	char   name[NETWORK_GRF_NAME_LENGTH];
+	GRFTextWrapper *name;
 };
 
 /**
@@ -662,11 +684,11 @@
  * @param md5sum the MD5 checksum part of the 'unique' GRF identifier
  * @param create whether to create a new GRFConfig if the GRFConfig did not
  *               exist in the fake list of GRFConfigs.
- * @return the GRFConfig with the given GRF ID and MD5 checksum or NULL when
- *         it does not exist and create is false. This value must NEVER be
- *         freed by the caller.
+ * @return The GRFTextWrapper of the name of the GRFConfig with the given GRF ID
+ *         and MD5 checksum or NULL when it does not exist and create is false.
+ *         This value must NEVER be freed by the caller.
  */
-char *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
+GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
 {
 	UnknownGRF *grf;
 	static UnknownGRF *unknown_grfs = NULL;
@@ -682,7 +704,10 @@
 	grf = CallocT<UnknownGRF>(1);
 	grf->grfid = grfid;
 	grf->next  = unknown_grfs;
-	strecpy(grf->name, UNKNOWN_GRF_NAME_PLACEHOLDER, lastof(grf->name));
+	grf->name = new GRFTextWrapper();
+	grf->name->AddRef();
+
+	AddGRFTextToList(&grf->name->text, UNKNOWN_GRF_NAME_PLACEHOLDER);
 	memcpy(grf->md5sum, md5sum, sizeof(grf->md5sum));
 
 	unknown_grfs = grf;
--- a/src/newgrf_config.h
+++ b/src/newgrf_config.h
@@ -15,6 +15,7 @@
 #include "strings_type.h"
 #include "core/alloc_type.hpp"
 #include "core/smallmap_type.hpp"
+#include "misc/countedptr.hpp"
 
 /** GRF config bit flags */
 enum GCF_Flags {
@@ -129,6 +130,14 @@
 	void SetValue(struct GRFConfig *config, uint32 value);
 };
 
+/** Reference counted wrapper around a GRFText pointer. */
+struct GRFTextWrapper : public SimpleCountedObject {
+	struct GRFText *text; ///< The actual text
+
+	GRFTextWrapper();
+	~GRFTextWrapper();
+};
+
 /** Information about GRF, used in the game and (part of it) in savegames */
 struct GRFConfig : ZeroedMemoryAllocator {
 	GRFConfig(const char *filename = NULL);
@@ -138,8 +147,8 @@
 	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
 	char *filename;                                ///< Filename - either with or without full path
-	struct GRFText *name;                          ///< NOSAVE: GRF name (Action 0x08)
-	struct GRFText *info;                          ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
+	GRFTextWrapper *name;                          ///< NOSAVE: GRF name (Action 0x08)
+	GRFTextWrapper *info;                          ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
 	GRFError *error;                               ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B)
 
 	uint32 version;                                ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown
@@ -198,7 +207,7 @@
 #ifdef ENABLE_NETWORK
 /* For communication about GRFs over the network */
 #define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
-char *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
+GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
 #endif /* ENABLE_NETWORK */
 
 #endif /* NEWGRF_CONFIG_H */