mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +00:00
Config nodes: added the ability to clear out node values or create empty leaf nodes
This commit is contained in:
parent
043f901c80
commit
83144f80b7
|
@ -147,6 +147,7 @@
|
|||
*/
|
||||
|
||||
#include "Util/NewConfig.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Util
|
||||
{
|
||||
|
@ -251,6 +252,34 @@ namespace Util
|
|||
return os.str();
|
||||
}
|
||||
|
||||
// Adds an empty node (no value and where Empty() will return true)
|
||||
Node &Node::AddEmpty(const std::string &path)
|
||||
{
|
||||
std::vector<std::string> keys = Util::Format(path).Split('/');
|
||||
Node *parent = this;
|
||||
ptr_t node;
|
||||
for (size_t i = 0; i < keys.size(); i++)
|
||||
{
|
||||
bool leaf = i == keys.size() - 1;
|
||||
auto it = parent->m_children.find(keys[i]);
|
||||
if (leaf || it == parent->m_children.end())
|
||||
{
|
||||
// Create node at this level and leave it empty
|
||||
node = std::make_shared<Node>(keys[i]);
|
||||
// Attach node to parent and move down to next nesting level: last
|
||||
// created node is new parent
|
||||
AddChild(*parent, node);
|
||||
parent = node.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Descend deeper...
|
||||
parent = it->second.get();
|
||||
}
|
||||
}
|
||||
return *node;
|
||||
}
|
||||
|
||||
// Adds a newly-created node (which, among other things, implies no
|
||||
// children) as a child
|
||||
void Node::AddChild(Node &parent, ptr_t &node)
|
||||
|
@ -340,5 +369,20 @@ namespace Util
|
|||
{
|
||||
//std::cout << ">>> Destroyed " << m_key << " (" << this << ")" << std::endl;
|
||||
}
|
||||
|
||||
void PrintConfigTree(const Node &config, int indent_level, int tab_stops)
|
||||
{
|
||||
std::fill_n(std::ostream_iterator<char>(std::cout), tab_stops * indent_level, ' ');
|
||||
std::cout << config.Key();
|
||||
if (config.Exists())
|
||||
{
|
||||
std::cout << " = " << config.ValueAs<std::string>();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
for (const Node &child: config)
|
||||
{
|
||||
PrintConfigTree(child, indent_level + 1, tab_stops);
|
||||
}
|
||||
}
|
||||
} // Config
|
||||
} // Util
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Util
|
|||
|
||||
void CheckEmptyOrMissing() const;
|
||||
const Node &MissingNode(const std::string &key) const;
|
||||
Node &AddEmpty(const std::string &path);
|
||||
void AddChild(Node &parent, ptr_t &node);
|
||||
void DeepCopy(const Node &that);
|
||||
void Swap(Node &rhs);
|
||||
|
@ -168,6 +169,11 @@ namespace Util
|
|||
return m_value;
|
||||
}
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
m_value = nullptr;
|
||||
}
|
||||
|
||||
inline void SetValue(const std::shared_ptr<GenericValue> &value)
|
||||
{
|
||||
m_value = value;
|
||||
|
@ -222,32 +228,9 @@ namespace Util
|
|||
template <typename T>
|
||||
Node &Add(const std::string &path, const T &value)
|
||||
{
|
||||
std::vector<std::string> keys = Util::Format(path).Split('/');
|
||||
Node *parent = this;
|
||||
ptr_t node;
|
||||
for (size_t i = 0; i < keys.size(); i++)
|
||||
{
|
||||
bool leaf = i == keys.size() - 1;
|
||||
auto it = parent->m_children.find(keys[i]);
|
||||
if (leaf || it == parent->m_children.end())
|
||||
{
|
||||
// Create node at this level
|
||||
node = std::make_shared<Node>(keys[i]);
|
||||
// The leaf node gets the value
|
||||
if (leaf)
|
||||
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();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Descend deeper...
|
||||
parent = it->second.get();
|
||||
}
|
||||
}
|
||||
return *node;
|
||||
Node &new_leaf_node = AddEmpty(path);
|
||||
new_leaf_node.SetValue(value);
|
||||
return new_leaf_node;
|
||||
}
|
||||
|
||||
Node &Add(const std::string &path)
|
||||
|
@ -266,6 +249,19 @@ namespace Util
|
|||
Add(key, value);
|
||||
}
|
||||
|
||||
void SetEmpty(const std::string &key)
|
||||
{
|
||||
Node *node = TryGet(key);
|
||||
if (node)
|
||||
{
|
||||
node->Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEmpty(key);
|
||||
}
|
||||
}
|
||||
|
||||
// True if value is empty (does not exist)
|
||||
inline bool Empty() const
|
||||
{
|
||||
|
@ -312,6 +308,8 @@ namespace Util
|
|||
Node(Node&& that) noexcept;
|
||||
~Node();
|
||||
};
|
||||
|
||||
void PrintConfigTree(const Node &config, int indent_level = 0, int tab_stops = 2);
|
||||
} // Config
|
||||
} // Util
|
||||
|
||||
|
|
Loading…
Reference in a new issue