mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-03-06 14:27:44 +00:00
Config::Node::Add() now supports nested keys (e.g., Add("foo/bar/baz", "0") will create three nested config nodes)
This commit is contained in:
parent
24c341120a
commit
a84aacf80b
|
@ -125,20 +125,26 @@ namespace Util
|
|||
std::cout << ToString(indent_level);
|
||||
}
|
||||
|
||||
Node &Node::Add(const std::string &key)
|
||||
Node &Node::Add(const std::string &path, const std::string &value)
|
||||
{
|
||||
Ptr_t node = std::make_shared<Node>(key);
|
||||
AddChild(node);
|
||||
std::vector<std::string> keys = Util::Format(path).Split('/');
|
||||
Node *parent = this;
|
||||
Ptr_t node;
|
||||
for (size_t i = 0; i < keys.size(); i++)
|
||||
{
|
||||
// Create node at this level
|
||||
node = std::make_shared<Node>(keys[i]);
|
||||
// The leaf node gets the value
|
||||
if (i == keys.size() - 1)
|
||||
node->SetValue(value);
|
||||
// Attach node to parent and move down to next nesting level: last
|
||||
// created node is new parent
|
||||
AddChild(*parent, node);
|
||||
parent = node.get();
|
||||
}
|
||||
return *node;
|
||||
}
|
||||
|
||||
Node &Node::Add(const std::string &key, const std::string &value)
|
||||
{
|
||||
Ptr_t node = std::make_shared<Node>(key, value);
|
||||
AddChild(node);
|
||||
return *node;
|
||||
}
|
||||
|
||||
void Node::Set(const std::string &key, const std::string &value)
|
||||
{
|
||||
Node &node = Get(key);
|
||||
|
@ -150,19 +156,19 @@ namespace Util
|
|||
|
||||
// Adds a newly-created node (which, among other things, implies no
|
||||
// children) as a child
|
||||
void Node::AddChild(Ptr_t &node)
|
||||
void Node::AddChild(Node &parent, Ptr_t &node)
|
||||
{
|
||||
if (!m_last_child)
|
||||
if (!parent.m_last_child)
|
||||
{
|
||||
m_first_child = node;
|
||||
m_last_child = node;
|
||||
parent.m_first_child = node;
|
||||
parent.m_last_child = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_last_child->m_next_sibling = node;
|
||||
m_last_child = node;
|
||||
parent.m_last_child->m_next_sibling = node;
|
||||
parent.m_last_child = node;
|
||||
}
|
||||
m_children[node->m_key] = node;
|
||||
parent.m_children[node->m_key] = node;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -203,7 +209,7 @@ namespace Util
|
|||
for (Ptr_t child = that.m_first_child; child; child = child->m_next_sibling)
|
||||
{
|
||||
Ptr_t copied_child = std::make_shared<Node>(*child);
|
||||
AddChild(copied_child);
|
||||
AddChild(*this, copied_child);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Util
|
|||
std::string m_value;
|
||||
static Node s_empty_node; // key, value, and children must always be empty
|
||||
|
||||
void AddChild(Ptr_t &node);
|
||||
void AddChild(Node &parent, Ptr_t &node);
|
||||
Node(); // prohibit accidental/unintentional creation of blank nodes
|
||||
friend Ptr_t CreateEmpty();
|
||||
|
||||
|
@ -187,9 +187,7 @@ namespace Util
|
|||
const Node &Get(const std::string &path) const;
|
||||
void Print(size_t indent_level = 0) const;
|
||||
std::string ToString(size_t indent_level = 0) const;
|
||||
//TODO: Add() needs to accept and correctly handle nested keys (e.g., "foo/bar/baz")
|
||||
Node &Add(const std::string &key);
|
||||
Node &Add(const std::string &key, const std::string &value);
|
||||
Node &Add(const std::string &key, const std::string &value = "");
|
||||
void Set(const std::string &key, const std::string &value);
|
||||
Node(const std::string &key);
|
||||
Node(const std::string &key, const std::string &value);
|
||||
|
|
|
@ -56,7 +56,7 @@ int main()
|
|||
std::cout << "Actual config tree:" << std::endl << std::endl;
|
||||
root->Print();
|
||||
std::cout << std::endl;
|
||||
test_results.push_back({ "Manual Creation", root->ToString() == expected_output });
|
||||
test_results.push_back({ "Manual", root->ToString() == expected_output });
|
||||
|
||||
// Expect second crom: bar.bin
|
||||
auto &global = *root;
|
||||
|
@ -140,6 +140,26 @@ int main()
|
|||
std::cout << std::endl;
|
||||
test_results.push_back({ "XML", xml_config->ToString() == expected_xml_config_tree });
|
||||
|
||||
// Create a nested key
|
||||
{
|
||||
Util::Config::Node::Ptr_t config = Util::Config::CreateEmpty();
|
||||
config->Add("foo/bar/baz", "bart");
|
||||
config->Print();
|
||||
std::cout << std::endl;
|
||||
test_results.push_back({ "Nested key 1", config->Get("foo/bar/baz").Value() == "bart" });
|
||||
config->Get("foo/bar/baz").Set("x", "xx");
|
||||
config->Get("foo/bar/baz").Set("y/z", "zz");
|
||||
config->Print();
|
||||
std::cout << std::endl;
|
||||
test_results.push_back({ "Nested key 2", config->Get("foo/bar/baz/x").Value() == "xx" });
|
||||
test_results.push_back({ "Nested key 3", config->Get("foo/bar/baz/y/z").Value() == "zz" });
|
||||
config->Add("a/b/c");
|
||||
config->Get("a/b/c").SetValue("d");
|
||||
config->Print();
|
||||
std::cout << std::endl;
|
||||
test_results.push_back({ "Nested key 4", config->Get("a/b/c").Value() == "d" });
|
||||
}
|
||||
|
||||
PrintTestResults(test_results);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue