Improve performance of string lookup in AddGRFString
This commit is contained in:
@@ -451,6 +451,17 @@ GRFFile *GetFileByGRFID(uint32 grfid)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a NewGRF file by its grfID, expect it to usually be the current GRF's grfID
|
||||||
|
* @param grfid The grfID to obtain the file for
|
||||||
|
* @return The file.
|
||||||
|
*/
|
||||||
|
GRFFile *GetFileByGRFIDExpectCurrent(uint32 grfid)
|
||||||
|
{
|
||||||
|
if (_cur.grffile->grfid == grfid) return _cur.grffile;
|
||||||
|
return GetFileByGRFID(grfid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a NewGRF file by its filename
|
* Obtain a NewGRF file by its filename
|
||||||
* @param filename The filename to obtain the file for.
|
* @param filename The filename to obtain the file for.
|
||||||
@@ -11943,6 +11954,9 @@ void LoadNewGRF(uint load_index, uint num_baseset)
|
|||||||
|
|
||||||
/* Pseudo sprite processing is finished; free temporary stuff */
|
/* Pseudo sprite processing is finished; free temporary stuff */
|
||||||
_cur.ClearDataForNextFile();
|
_cur.ClearDataForNextFile();
|
||||||
|
for (GRFFile * const file : _grf_files) {
|
||||||
|
file->string_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/* Call any functions that should be run after GRFs have been loaded. */
|
/* Call any functions that should be run after GRFs have been loaded. */
|
||||||
AfterLoadGRFs();
|
AfterLoadGRFs();
|
||||||
|
|||||||
@@ -348,6 +348,8 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||||||
|
|
||||||
byte ctrl_flags; ///< General GRF control flags
|
byte ctrl_flags; ///< General GRF control flags
|
||||||
|
|
||||||
|
btree::btree_map<uint16, uint> string_map; ///< Map of local GRF string ID to string ID
|
||||||
|
|
||||||
GRFFile(const struct GRFConfig *config);
|
GRFFile(const struct GRFConfig *config);
|
||||||
~GRFFile();
|
~GRFFile();
|
||||||
|
|
||||||
|
|||||||
@@ -573,23 +573,30 @@ StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool ne
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint id;
|
uint id;
|
||||||
for (id = 0; id < _num_grf_texts; id++) {
|
extern GRFFile *GetFileByGRFIDExpectCurrent(uint32 grfid);
|
||||||
if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) {
|
GRFFile *grf = GetFileByGRFIDExpectCurrent(grfid);
|
||||||
break;
|
if (grf == nullptr) return STR_EMPTY;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Too many strings allocated, return empty */
|
auto iter = grf->string_map.lower_bound(stringid);
|
||||||
if (id == lengthof(_grf_text)) {
|
if (iter != grf->string_map.end() && iter->first == stringid) {
|
||||||
_grf_bug_too_many_strings = true;
|
/* Found */
|
||||||
return STR_EMPTY;
|
id = iter->second;
|
||||||
|
} else {
|
||||||
|
/* Allocate new ID */
|
||||||
|
id = _num_grf_texts;
|
||||||
|
|
||||||
|
/* Too many strings allocated, return empty */
|
||||||
|
if (id == lengthof(_grf_text)) {
|
||||||
|
_grf_bug_too_many_strings = true;
|
||||||
|
return STR_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
grf->string_map.insert(iter, std::make_pair(stringid, id));
|
||||||
|
_num_grf_texts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string newtext = TranslateTTDPatchCodes(grfid, langid_to_add, allow_newlines, text_to_add);
|
std::string newtext = TranslateTTDPatchCodes(grfid, langid_to_add, allow_newlines, text_to_add);
|
||||||
|
|
||||||
/* If we didn't find our stringid and grfid in the list, allocate a new id */
|
|
||||||
if (id == _num_grf_texts) _num_grf_texts++;
|
|
||||||
|
|
||||||
if (_grf_text[id].textholder.empty()) {
|
if (_grf_text[id].textholder.empty()) {
|
||||||
_grf_text[id].grfid = grfid;
|
_grf_text[id].grfid = grfid;
|
||||||
_grf_text[id].stringid = stringid;
|
_grf_text[id].stringid = stringid;
|
||||||
|
|||||||
Reference in New Issue
Block a user