Skip to content

Commit

Permalink
[glass] Storage: Use std::map instead of wpi::StringMap
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterJohnson committed Oct 23, 2024
1 parent a3b12b3 commit 69359ed
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 99 deletions.
164 changes: 76 additions & 88 deletions glass/src/lib/native/cpp/Storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,15 @@ Storage::Value* Storage::FindValue(std::string_view key) {
if (it == m_values.end()) {
return nullptr;
}
return it->second.get();
return &it->second;
}

Storage::Value& Storage::GetValue(std::string_view key) {
auto& val = m_values[key];
if (!val) {
val = std::make_unique<Value>();
auto it = m_values.find(key);
if (it == m_values.end()) {
it = m_values.emplace_hint(it, key, Value::kNone);
}
return *val;
return it->second;
}

#define DEFUN(CapsName, LowerName, CType, CParamType, ArrCType) \
Expand All @@ -216,7 +216,7 @@ Storage::Value& Storage::GetValue(std::string_view key) {
if (it == m_values.end()) { \
return CType{defaultVal}; \
} \
Value& value = *it->second; \
Value& value = it->second; \
if (value.type != Value::k##CapsName) { \
if (!Convert##CapsName(&value)) { \
value.Reset(Value::k##CapsName); \
Expand All @@ -229,66 +229,68 @@ Storage::Value& Storage::GetValue(std::string_view key) {
} \
\
void Storage::Set##CapsName(std::string_view key, CParamType val) { \
auto& valuePtr = m_values[key]; \
if (!valuePtr) { \
valuePtr = std::make_unique<Value>(Value::k##CapsName); \
auto it = m_values.find(key); \
if (it == m_values.end()) { \
it = m_values.emplace_hint(it, key, Value::k##CapsName); \
} else { \
valuePtr->Reset(Value::k##CapsName); \
it->second.Reset(Value::k##CapsName); \
} \
valuePtr->LowerName##Val = val; \
valuePtr->LowerName##Default = {}; \
it->second.LowerName##Val = val; \
it->second.LowerName##Default = {}; \
} \
\
CType& Storage::Get##CapsName(std::string_view key, CParamType defaultVal) { \
auto& valuePtr = m_values[key]; \
bool setValue = false; \
if (!valuePtr) { \
valuePtr = std::make_unique<Value>(Value::k##CapsName); \
auto it = m_values.find(key); \
if (it == m_values.end()) { \
it = m_values.emplace_hint(it, key, Value::k##CapsName); \
setValue = true; \
} else if (valuePtr->type != Value::k##CapsName) { \
if (!Convert##CapsName(valuePtr.get())) { \
valuePtr->Reset(Value::k##CapsName); \
} else if (it->second.type != Value::k##CapsName) { \
if (!Convert##CapsName(&it->second)) { \
it->second.Reset(Value::k##CapsName); \
setValue = true; \
} \
} \
Value& value = it->second; \
if (setValue) { \
valuePtr->LowerName##Val = defaultVal; \
value.LowerName##Val = defaultVal; \
} \
if (!valuePtr->hasDefault) { \
valuePtr->LowerName##Default = defaultVal; \
valuePtr->hasDefault = true; \
if (!value.hasDefault) { \
value.LowerName##Default = defaultVal; \
value.hasDefault = true; \
} \
return valuePtr->LowerName##Val; \
return value.LowerName##Val; \
} \
\
std::vector<ArrCType>& Storage::Get##CapsName##Array( \
std::string_view key, std::span<const ArrCType> defaultVal) { \
auto& valuePtr = m_values[key]; \
bool setValue = false; \
if (!valuePtr) { \
valuePtr = std::make_unique<Value>(Value::k##CapsName##Array); \
auto it = m_values.find(key); \
if (it == m_values.end()) { \
it = m_values.emplace_hint(it, key, Value::k##CapsName##Array); \
setValue = true; \
} else if (valuePtr->type != Value::k##CapsName##Array) { \
if (!Convert##CapsName##Array(valuePtr.get())) { \
valuePtr->Reset(Value::k##CapsName##Array); \
} else if (it->second.type != Value::k##CapsName##Array) { \
if (!Convert##CapsName##Array(&it->second)) { \
it->second.Reset(Value::k##CapsName##Array); \
setValue = true; \
} \
} \
Value& value = it->second; \
if (setValue) { \
valuePtr->LowerName##Array = \
value.LowerName##Array = \
new std::vector<ArrCType>{defaultVal.begin(), defaultVal.end()}; \
} \
if (!valuePtr->hasDefault) { \
if (!value.hasDefault) { \
if (defaultVal.empty()) { \
valuePtr->LowerName##ArrayDefault = nullptr; \
value.LowerName##ArrayDefault = nullptr; \
} else { \
valuePtr->LowerName##ArrayDefault = \
value.LowerName##ArrayDefault = \
new std::vector<ArrCType>{defaultVal.begin(), defaultVal.end()}; \
} \
valuePtr->hasDefault = true; \
value.hasDefault = true; \
} \
assert(valuePtr->LowerName##Array); \
return *valuePtr->LowerName##Array; \
assert(value.LowerName##Array); \
return *value.LowerName##Array; \
}

DEFUN(Int, int, int, int, int)
Expand All @@ -303,47 +305,38 @@ Storage& Storage::GetChild(std::string_view label_id) {
if (id.empty()) {
id = label;
}
auto& childPtr = m_values[id];
if (!childPtr) {
childPtr = std::make_unique<Value>();
}
if (childPtr->type != Value::kChild) {
childPtr->Reset(Value::kChild);
childPtr->child = new Storage;
Value& childValue = GetValue(id);
if (childValue.type != Value::kChild) {
childValue.Reset(Value::kChild);
childValue.child = new Storage;
}
return *childPtr->child;
return *childValue.child;
}

std::vector<std::unique_ptr<Storage>>& Storage::GetChildArray(
std::string_view key) {
auto& valuePtr = m_values[key];
if (!valuePtr) {
valuePtr = std::make_unique<Value>(Value::kChildArray);
valuePtr->childArray = new std::vector<std::unique_ptr<Storage>>();
} else if (valuePtr->type != Value::kChildArray) {
valuePtr->Reset(Value::kChildArray);
valuePtr->childArray = new std::vector<std::unique_ptr<Storage>>();
auto it = m_values.find(key);
if (it == m_values.end()) {
it = m_values.emplace_hint(it, key, Value::kChildArray);
it->second.childArray = new std::vector<std::unique_ptr<Storage>>();
} else if (it->second.type != Value::kChildArray) {
it->second.Reset(Value::kChildArray);
it->second.childArray = new std::vector<std::unique_ptr<Storage>>();
}

return *valuePtr->childArray;
return *it->second.childArray;
}

std::unique_ptr<Storage::Value> Storage::Erase(std::string_view key) {
void Storage::Erase(std::string_view key) {
auto it = m_values.find(key);
if (it != m_values.end()) {
auto rv = std::move(it->getValue());
m_values.erase(it);
return rv;
}
return nullptr;
}

void Storage::EraseChildren() {
for (auto&& kv : m_values) {
if (kv.getValue()->type == Value::kChild) {
m_values.remove(&kv);
}
}
std::erase_if(m_values,
[](const auto& kv) { return kv.second.type == Value::kChild; });
}

static bool JsonArrayToStorage(Storage::Value* valuePtr, const wpi::json& jarr,
Expand Down Expand Up @@ -475,52 +468,47 @@ bool Storage::FromJson(const wpi::json& json, const char* filename) {
return false;
}
for (auto&& jkv : json.items()) {
auto& valuePtr = m_values[jkv.key()];
bool created = false;
if (!valuePtr) {
valuePtr = std::make_unique<Value>();
created = true;
}
auto [it, created] = m_values.try_emplace(jkv.key());
auto& jvalue = jkv.value();
switch (jvalue.type()) {
case wpi::json::value_t::boolean:
valuePtr->Reset(Value::kBool);
valuePtr->boolVal = jvalue.get<bool>();
it->second.Reset(Value::kBool);
it->second.boolVal = jvalue.get<bool>();
break;
case wpi::json::value_t::number_float:
valuePtr->Reset(Value::kDouble);
valuePtr->doubleVal = jvalue.get<double>();
it->second.Reset(Value::kDouble);
it->second.doubleVal = jvalue.get<double>();
break;
case wpi::json::value_t::number_integer:
valuePtr->Reset(Value::kInt64);
valuePtr->int64Val = jvalue.get<int64_t>();
it->second.Reset(Value::kInt64);
it->second.int64Val = jvalue.get<int64_t>();
break;
case wpi::json::value_t::number_unsigned:
valuePtr->Reset(Value::kInt64);
valuePtr->int64Val = jvalue.get<uint64_t>();
it->second.Reset(Value::kInt64);
it->second.int64Val = jvalue.get<uint64_t>();
break;
case wpi::json::value_t::string:
valuePtr->Reset(Value::kString);
valuePtr->stringVal = jvalue.get_ref<const std::string&>();
it->second.Reset(Value::kString);
it->second.stringVal = jvalue.get_ref<const std::string&>();
break;
case wpi::json::value_t::object:
if (valuePtr->type != Value::kChild) {
valuePtr->Reset(Value::kChild);
valuePtr->child = new Storage;
if (it->second.type != Value::kChild) {
it->second.Reset(Value::kChild);
it->second.child = new Storage;
}
valuePtr->child->FromJson(jvalue, filename); // recurse
it->second.child->FromJson(jvalue, filename); // recurse
break;
case wpi::json::value_t::array:
if (!JsonArrayToStorage(valuePtr.get(), jvalue, filename)) {
if (!JsonArrayToStorage(&it->second, jvalue, filename)) {
if (created) {
m_values.erase(jkv.key());
m_values.erase(it);
}
}
break;
default:
ImGui::LogText("null value in %s, ignoring", filename);
if (created) {
m_values.erase(jkv.key());
m_values.erase(it);
}
break;
}
Expand Down Expand Up @@ -559,7 +547,7 @@ wpi::json Storage::ToJson() const {
wpi::json j = wpi::json::object();
for (auto&& kv : m_values) {
wpi::json jelem;
auto& value = *kv.getValue();
Value& value = kv.second;
switch (value.type) {
#define CASE(CapsName, LowerName) \
case Value::k##CapsName: \
Expand Down Expand Up @@ -602,7 +590,7 @@ wpi::json Storage::ToJson() const {
default:
continue;
}
j.emplace(kv.getKey(), std::move(jelem));
j.emplace(kv.first, std::move(jelem));
}
return j;
}
Expand All @@ -617,7 +605,7 @@ void Storage::Clear() {

void Storage::ClearValues() {
for (auto&& kv : m_values) {
auto& value = *kv.getValue();
Value& value = kv.second;
switch (value.type) {
case Value::kInt:
value.intVal = value.intDefault;
Expand Down Expand Up @@ -703,7 +691,7 @@ void Storage::Apply() {

void Storage::ApplyChildren() {
for (auto&& kv : m_values) {
auto& value = *kv.getValue();
Value& value = kv.second;
switch (value.type) {
case Value::kChild:
value.child->Apply();
Expand Down
Loading

0 comments on commit 69359ed

Please sign in to comment.