diff --git a/common/entdata.cc b/common/entdata.cc index abf2f517..7ba2f9b4 100644 --- a/common/entdata.cc +++ b/common/entdata.cc @@ -28,6 +28,71 @@ #include #include +const std::string& entdict_t::get(const std::string& key) const { + if (auto it = find(key); it != keyvalues.end()) { + return it->second; + } + + static std::string empty; + return empty; +} + +void entdict_t::set(const std::string& key, const std::string& value) { + // search for existing key to update + if (auto it = find(key); it != keyvalues.end()) { + // found existing key + it->second = value; + return; + } + + // no existing key; add new + keyvalues.push_back(std::make_pair(key, value)); +} + +void entdict_t::remove(const std::string& key) { + if (auto it = find(key); it != keyvalues.end()) { + keyvalues.erase(it); + } +} + +keyvalues_t::iterator entdict_t::find(std::string_view key) { + auto existingIt = keyvalues.end(); + for (auto it = keyvalues.begin(); it != keyvalues.end(); ++it) { + if (key == it->first) { + existingIt = it; + break; + } + } + return existingIt; +} + +keyvalues_t::const_iterator entdict_t::find(std::string_view key) const { + auto existingIt = keyvalues.end(); + for (auto it = keyvalues.begin(); it != keyvalues.end(); ++it) { + if (key == it->first) { + existingIt = it; + break; + } + } + return existingIt; +} + +keyvalues_t::const_iterator entdict_t::begin() const { + return keyvalues.begin(); +} + +keyvalues_t::const_iterator entdict_t::end() const { + return keyvalues.end(); +} + +keyvalues_t::iterator entdict_t::begin() { + return keyvalues.begin(); +} + +keyvalues_t::iterator entdict_t::end() { + return keyvalues.end(); +} + /* * ================== * EntData_Parse @@ -77,7 +142,7 @@ EntData_Parse(const char *entdata) if (valstring.length() > MAX_ENT_VALUE - 1) Error("%s: Value length > %i", __func__, MAX_ENT_VALUE - 1); - entity[keystr] = valstring; + entity.set(keystr, valstring); } result.push_back(entity); @@ -108,17 +173,13 @@ EntData_Write(const std::vector &ents) std::string EntDict_StringForKey(const entdict_t &dict, const std::string key) { - auto it = dict.find(key); - if (it != dict.end()) { - return it->second; - } - return ""; + return dict.get(key); } float EntDict_FloatForKey(const entdict_t &dict, const std::string key) { - auto s = EntDict_StringForKey(dict, key); + auto s = dict.get(key); if (s.empty()) return 0; @@ -132,11 +193,7 @@ EntDict_FloatForKey(const entdict_t &dict, const std::string key) void EntDict_RemoveValueForKey(entdict_t &dict, const std::string &key) { - const auto it = dict.find(key); - if (it != dict.end()) { - dict.erase(it); - } - Q_assert(dict.find(key) == dict.end()); + dict.remove(key); } void //mxd @@ -144,7 +201,9 @@ EntDict_RenameKey(entdict_t &dict, const std::string &from, const std::string &t { const auto it = dict.find(from); if (it != dict.end()) { - swap(dict[to], it->second); - dict.erase(it); + const auto oldValue = it->second; + + dict.remove(from); + dict.set(to, oldValue); } } diff --git a/include/common/entdata.h b/include/common/entdata.h index 2ee983de..675e32de 100644 --- a/include/common/entdata.h +++ b/include/common/entdata.h @@ -17,11 +17,32 @@ See file, 'COPYING', for details. */ +#pragma once + #include #include +#include #include -using entdict_t = std::map; +using keyvalue_t = std::pair; +using keyvalues_t = std::vector; + +class entdict_t { + keyvalues_t keyvalues; +public: + const std::string& get(const std::string& key) const; + void set(const std::string& key, const std::string& value); + void remove(const std::string& key); + + keyvalues_t::iterator find(std::string_view key); + keyvalues_t::const_iterator find(std::string_view key) const; + + keyvalues_t::const_iterator begin() const; + keyvalues_t::const_iterator end() const; + + keyvalues_t::iterator begin(); + keyvalues_t::iterator end(); +}; std::vector EntData_Parse(const char *entdata); std::string EntData_Write(const std::vector &ents); diff --git a/include/light/settings.hh b/include/light/settings.hh index 335a37b6..bc72b1f7 100644 --- a/include/light/settings.hh +++ b/include/light/settings.hh @@ -20,6 +20,7 @@ #ifndef __LIGHT_SETTINGS_H__ #define __LIGHT_SETTINGS_H__ +#include #include #include @@ -352,7 +353,7 @@ public: setting->setStringValue(value, cmdline); } - void setSettings(const std::map &epairs, bool cmdline) { + void setSettings(const entdict_t &epairs, bool cmdline) { for (const auto &epair : epairs) { setSetting(epair.first, epair.second, cmdline); } diff --git a/light/entities.cc b/light/entities.cc index 8fc4a3b4..033e3434 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -65,7 +65,7 @@ static std::vector> lightstyleForTargetname; static entdict_t &WorldEnt() { if (entdicts.size() == 0 - || entdicts.at(0)["classname"] != "worldspawn") { + || entdicts.at(0).get("classname") != "worldspawn") { Error("WorldEnt() failed to get worldspawn"); } return entdicts.at(0); @@ -73,7 +73,7 @@ static entdict_t &WorldEnt() void SetWorldKeyValue(const std::string &key, const std::string &value) { - WorldEnt()[key] = value; + WorldEnt().set(key, value); } std::string WorldValueForKey(const std::string &key) { @@ -953,9 +953,9 @@ LoadEntities(const globalconfig_t &cfg, const mbsp_t *bsp) const std::string lmscale = EntDict_StringForKey(entdict, "lightmap_scale"); if (!lmscale.empty()) { logprint("lightmap_scale should be _lightmap_scale\n"); - - entdict.erase(entdict.find("lightmap_scale")); - entdict["_lightmap_scale"] = lmscale; + + EntDict_RemoveValueForKey(entdict,"lightmap_scale"); + entdict.set("_lightmap_scale", lmscale); } // setup light styles for switchable lights @@ -965,7 +965,7 @@ LoadEntities(const globalconfig_t &cfg, const mbsp_t *bsp) const std::string targetname = EntDict_StringForKey(entdict, "targetname"); if (!targetname.empty()) { const int style = LightStyleForTargetname(cfg, targetname); - entdict["style"] = std::to_string(style); + entdict.set("style", std::to_string(style)); } } @@ -975,7 +975,7 @@ LoadEntities(const globalconfig_t &cfg, const mbsp_t *bsp) // if targetname is "", generates a new unique lightstyle const int style = LightStyleForTargetname(cfg, targetname); // TODO: Configurable key? - entdict["switchshadstyle"] = std::to_string(style); + entdict.set("switchshadstyle", std::to_string(style)); } // parse escape sequences @@ -1009,7 +1009,7 @@ LoadEntities(const globalconfig_t &cfg, const mbsp_t *bsp) if(anglescale != entdict.end()) { // Convert from 0..2 to 0..1 range... const float val = qmin(1.0f, qmax(0.0f, EntDict_FloatForKey(entdict, "_anglescale") * 0.5f)); - entdict["_anglescale"] = std::to_string(val); + entdict.set("_anglescale", std::to_string(val)); } } @@ -1305,7 +1305,7 @@ SurfLights_WriteEntityToFile(FILE *f, light_t *entity, const vec3_t pos) entdict_t epairs { *entity->epairs }; EntDict_RemoveValueForKey(epairs, "_surface"); - epairs["origin"] = VecStr(pos); + epairs.set("origin", VecStr(pos)); std::string entstring = EntData_Write({ epairs }); fwrite(entstring.data(), 1, entstring.size(), f); @@ -1513,7 +1513,7 @@ bool ParseLightsFile(const char *fname) if (!t) continue; entdict_t d = {}; - d["_surface"] = std::string(com_token); + d.set("_surface", std::string(com_token)); t = COM_Parse(t); r = atof(com_token); t = COM_Parse(t); @@ -1521,9 +1521,9 @@ bool ParseLightsFile(const char *fname) t = COM_Parse(t); b = atof(com_token); q_snprintf(gah, sizeof(gah), "%f %f %f", r,g,b); - d["_color"] = std::string(gah); + d.set("_color", std::string(gah)); t = COM_Parse(t); - d["light"] = std::string(com_token); + d.set("light", std::string(com_token)); //might be hdr rgbi values here radlights.push_back(d);