common: preserve order of key/value pairs
This commit is contained in:
parent
c8b2f6f8e6
commit
fea7849315
|
|
@ -28,6 +28,71 @@
|
||||||
#include <light/ltface.hh>
|
#include <light/ltface.hh>
|
||||||
#include <common/bsputils.hh>
|
#include <common/bsputils.hh>
|
||||||
|
|
||||||
|
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
|
* EntData_Parse
|
||||||
|
|
@ -77,7 +142,7 @@ EntData_Parse(const char *entdata)
|
||||||
if (valstring.length() > MAX_ENT_VALUE - 1)
|
if (valstring.length() > MAX_ENT_VALUE - 1)
|
||||||
Error("%s: Value length > %i", __func__, 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);
|
result.push_back(entity);
|
||||||
|
|
@ -108,17 +173,13 @@ EntData_Write(const std::vector<entdict_t> &ents)
|
||||||
std::string
|
std::string
|
||||||
EntDict_StringForKey(const entdict_t &dict, const std::string key)
|
EntDict_StringForKey(const entdict_t &dict, const std::string key)
|
||||||
{
|
{
|
||||||
auto it = dict.find(key);
|
return dict.get(key);
|
||||||
if (it != dict.end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
EntDict_FloatForKey(const entdict_t &dict, const std::string key)
|
EntDict_FloatForKey(const entdict_t &dict, const std::string key)
|
||||||
{
|
{
|
||||||
auto s = EntDict_StringForKey(dict, key);
|
auto s = dict.get(key);
|
||||||
if (s.empty())
|
if (s.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -132,11 +193,7 @@ EntDict_FloatForKey(const entdict_t &dict, const std::string key)
|
||||||
void
|
void
|
||||||
EntDict_RemoveValueForKey(entdict_t &dict, const std::string &key)
|
EntDict_RemoveValueForKey(entdict_t &dict, const std::string &key)
|
||||||
{
|
{
|
||||||
const auto it = dict.find(key);
|
dict.remove(key);
|
||||||
if (it != dict.end()) {
|
|
||||||
dict.erase(it);
|
|
||||||
}
|
|
||||||
Q_assert(dict.find(key) == dict.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void //mxd
|
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);
|
const auto it = dict.find(from);
|
||||||
if (it != dict.end()) {
|
if (it != dict.end()) {
|
||||||
swap(dict[to], it->second);
|
const auto oldValue = it->second;
|
||||||
dict.erase(it);
|
|
||||||
|
dict.remove(from);
|
||||||
|
dict.set(to, oldValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,32 @@
|
||||||
See file, 'COPYING', for details.
|
See file, 'COPYING', for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using entdict_t = std::map<std::string, std::string>;
|
using keyvalue_t = std::pair<std::string, std::string>;
|
||||||
|
using keyvalues_t = std::vector<keyvalue_t>;
|
||||||
|
|
||||||
|
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<entdict_t> EntData_Parse(const char *entdata);
|
std::vector<entdict_t> EntData_Parse(const char *entdata);
|
||||||
std::string EntData_Write(const std::vector<entdict_t> &ents);
|
std::string EntData_Write(const std::vector<entdict_t> &ents);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#ifndef __LIGHT_SETTINGS_H__
|
#ifndef __LIGHT_SETTINGS_H__
|
||||||
#define __LIGHT_SETTINGS_H__
|
#define __LIGHT_SETTINGS_H__
|
||||||
|
|
||||||
|
#include <common/entdata.h>
|
||||||
#include <common/log.hh>
|
#include <common/log.hh>
|
||||||
#include <common/mathlib.hh>
|
#include <common/mathlib.hh>
|
||||||
|
|
||||||
|
|
@ -352,7 +353,7 @@ public:
|
||||||
setting->setStringValue(value, cmdline);
|
setting->setStringValue(value, cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSettings(const std::map<std::string, std::string> &epairs, bool cmdline) {
|
void setSettings(const entdict_t &epairs, bool cmdline) {
|
||||||
for (const auto &epair : epairs) {
|
for (const auto &epair : epairs) {
|
||||||
setSetting(epair.first, epair.second, cmdline);
|
setSetting(epair.first, epair.second, cmdline);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ static std::vector<std::pair<std::string, int>> lightstyleForTargetname;
|
||||||
static entdict_t &WorldEnt()
|
static entdict_t &WorldEnt()
|
||||||
{
|
{
|
||||||
if (entdicts.size() == 0
|
if (entdicts.size() == 0
|
||||||
|| entdicts.at(0)["classname"] != "worldspawn") {
|
|| entdicts.at(0).get("classname") != "worldspawn") {
|
||||||
Error("WorldEnt() failed to get worldspawn");
|
Error("WorldEnt() failed to get worldspawn");
|
||||||
}
|
}
|
||||||
return entdicts.at(0);
|
return entdicts.at(0);
|
||||||
|
|
@ -73,7 +73,7 @@ static entdict_t &WorldEnt()
|
||||||
|
|
||||||
void SetWorldKeyValue(const std::string &key, const std::string &value)
|
void SetWorldKeyValue(const std::string &key, const std::string &value)
|
||||||
{
|
{
|
||||||
WorldEnt()[key] = value;
|
WorldEnt().set(key, value);
|
||||||
}
|
}
|
||||||
std::string WorldValueForKey(const std::string &key)
|
std::string WorldValueForKey(const std::string &key)
|
||||||
{
|
{
|
||||||
|
|
@ -954,8 +954,8 @@ LoadEntities(const globalconfig_t &cfg, const mbsp_t *bsp)
|
||||||
if (!lmscale.empty()) {
|
if (!lmscale.empty()) {
|
||||||
logprint("lightmap_scale should be _lightmap_scale\n");
|
logprint("lightmap_scale should be _lightmap_scale\n");
|
||||||
|
|
||||||
entdict.erase(entdict.find("lightmap_scale"));
|
EntDict_RemoveValueForKey(entdict,"lightmap_scale");
|
||||||
entdict["_lightmap_scale"] = lmscale;
|
entdict.set("_lightmap_scale", lmscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup light styles for switchable lights
|
// 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");
|
const std::string targetname = EntDict_StringForKey(entdict, "targetname");
|
||||||
if (!targetname.empty()) {
|
if (!targetname.empty()) {
|
||||||
const int style = LightStyleForTargetname(cfg, targetname);
|
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
|
// if targetname is "", generates a new unique lightstyle
|
||||||
const int style = LightStyleForTargetname(cfg, targetname);
|
const int style = LightStyleForTargetname(cfg, targetname);
|
||||||
// TODO: Configurable key?
|
// TODO: Configurable key?
|
||||||
entdict["switchshadstyle"] = std::to_string(style);
|
entdict.set("switchshadstyle", std::to_string(style));
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse escape sequences
|
// parse escape sequences
|
||||||
|
|
@ -1009,7 +1009,7 @@ LoadEntities(const globalconfig_t &cfg, const mbsp_t *bsp)
|
||||||
if(anglescale != entdict.end()) {
|
if(anglescale != entdict.end()) {
|
||||||
// Convert from 0..2 to 0..1 range...
|
// Convert from 0..2 to 0..1 range...
|
||||||
const float val = qmin(1.0f, qmax(0.0f, EntDict_FloatForKey(entdict, "_anglescale") * 0.5f));
|
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_t epairs { *entity->epairs };
|
||||||
EntDict_RemoveValueForKey(epairs, "_surface");
|
EntDict_RemoveValueForKey(epairs, "_surface");
|
||||||
epairs["origin"] = VecStr(pos);
|
epairs.set("origin", VecStr(pos));
|
||||||
|
|
||||||
std::string entstring = EntData_Write({ epairs });
|
std::string entstring = EntData_Write({ epairs });
|
||||||
fwrite(entstring.data(), 1, entstring.size(), f);
|
fwrite(entstring.data(), 1, entstring.size(), f);
|
||||||
|
|
@ -1513,7 +1513,7 @@ bool ParseLightsFile(const char *fname)
|
||||||
if (!t)
|
if (!t)
|
||||||
continue;
|
continue;
|
||||||
entdict_t d = {};
|
entdict_t d = {};
|
||||||
d["_surface"] = std::string(com_token);
|
d.set("_surface", std::string(com_token));
|
||||||
t = COM_Parse(t);
|
t = COM_Parse(t);
|
||||||
r = atof(com_token);
|
r = atof(com_token);
|
||||||
t = COM_Parse(t);
|
t = COM_Parse(t);
|
||||||
|
|
@ -1521,9 +1521,9 @@ bool ParseLightsFile(const char *fname)
|
||||||
t = COM_Parse(t);
|
t = COM_Parse(t);
|
||||||
b = atof(com_token);
|
b = atof(com_token);
|
||||||
q_snprintf(gah, sizeof(gah), "%f %f %f", r,g,b);
|
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);
|
t = COM_Parse(t);
|
||||||
d["light"] = std::string(com_token);
|
d.set("light", std::string(com_token));
|
||||||
//might be hdr rgbi values here
|
//might be hdr rgbi values here
|
||||||
|
|
||||||
radlights.push_back(d);
|
radlights.push_back(d);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue