mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
DOM: Implemented DOM::Node object
This commit is contained in:
parent
eba68ac2ff
commit
4c53da5be1
2 changed files with 128 additions and 51 deletions
163
src/DOM.cpp
163
src/DOM.cpp
|
@ -491,17 +491,19 @@ DOM::~DOM ()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void DOM::addSource (
|
void DOM::addSource (
|
||||||
const std::string&,
|
const std::string& reference,
|
||||||
bool (*provider)(const std::string&, Variant&))
|
bool (*provider)(const std::string&, Variant&))
|
||||||
{
|
{
|
||||||
// TODO Implement.
|
if (_node == nullptr)
|
||||||
|
_node = new DOM::Node ();
|
||||||
|
|
||||||
|
_node->addSource (reference, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool DOM::valid (const std::string& reference) const
|
bool DOM::valid (const std::string& reference) const
|
||||||
{
|
{
|
||||||
// TODO Implement.
|
return _node && _node->find (reference) != nullptr;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -509,100 +511,161 @@ Variant DOM::get (const std::string& reference) const
|
||||||
{
|
{
|
||||||
Variant v ("");
|
Variant v ("");
|
||||||
|
|
||||||
// Find the provider.
|
if (_node)
|
||||||
// TODO Start at the root of the tree.
|
|
||||||
for (const auto& element : decomposeReference (reference))
|
|
||||||
{
|
{
|
||||||
// TODO If tree contains a named node 'element', capture the provider, if any.
|
auto node = _node->find (reference);
|
||||||
|
if (node != nullptr &&
|
||||||
|
node->_provider != nullptr)
|
||||||
|
{
|
||||||
|
if (node->_provider (reference, v))
|
||||||
|
return v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::vector <std::string> DOM::decomposeReference (const std::string& reference) const
|
int DOM::count () const
|
||||||
|
{
|
||||||
|
if (_node)
|
||||||
|
return _node->count ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::vector <std::string> DOM::decomposeReference (const std::string& reference)
|
||||||
{
|
{
|
||||||
return split (reference, '.');
|
return split (reference, '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int DOM::count () const
|
std::string DOM::dump () const
|
||||||
{
|
{
|
||||||
// Recurse and count the branches.
|
if (_node)
|
||||||
int total {0};
|
return _node->dump ();
|
||||||
for (auto& i : _branches)
|
|
||||||
total += i->count ();
|
|
||||||
|
|
||||||
return total;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::shared_ptr <DOM> DOM::find (const std::string& path)
|
DOM::Node::~Node ()
|
||||||
{
|
{
|
||||||
std::vector <std::string> elements = split (path, '.');
|
for (auto& branch : _branches)
|
||||||
|
delete branch;
|
||||||
|
}
|
||||||
|
|
||||||
// Must start at the trunk.
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
auto cursor = std::make_shared <DOM> (*this);
|
void DOM::Node::addSource (
|
||||||
auto it = elements.begin ();
|
const std::string& reference,
|
||||||
if (cursor->_name != *it)
|
bool (*provider)(const std::string&, Variant&))
|
||||||
return nullptr;
|
{
|
||||||
|
auto cursor = this;
|
||||||
// Perhaps the trunk is what is needed?
|
for (const auto& element : DOM::decomposeReference (reference))
|
||||||
if (elements.size () == 1)
|
|
||||||
return cursor;
|
|
||||||
|
|
||||||
// Now look for the next branch.
|
|
||||||
for (++it; it != elements.end (); ++it)
|
|
||||||
{
|
{
|
||||||
bool found = false;
|
auto found {false};
|
||||||
|
for (auto& branch : cursor->_branches)
|
||||||
// If the cursor has a branch that matches *it, proceed.
|
|
||||||
for (auto i = cursor->_branches.begin (); i != cursor->_branches.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if ((*i)->_name == *it)
|
if (branch->_name == element)
|
||||||
{
|
{
|
||||||
cursor = *i;
|
cursor = branch;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! found)
|
if (! found)
|
||||||
return nullptr;
|
{
|
||||||
|
auto branch = new DOM::Node ();
|
||||||
|
branch->_name = element;
|
||||||
|
cursor->_branches.push_back (branch);
|
||||||
|
cursor = branch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cursor;
|
cursor->_provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string DOM::dumpNode (
|
// A valid reference is one that has a provider function.
|
||||||
const std::shared_ptr <DOM> t,
|
bool DOM::Node::valid (const std::string& reference) const
|
||||||
|
{
|
||||||
|
return find (reference) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const DOM::Node* DOM::Node::find (const std::string& reference) const
|
||||||
|
{
|
||||||
|
auto cursor = this;
|
||||||
|
for (const auto& element : DOM::decomposeReference (reference))
|
||||||
|
{
|
||||||
|
auto found {false};
|
||||||
|
for (auto& branch : cursor->_branches)
|
||||||
|
{
|
||||||
|
if (branch->_name == element)
|
||||||
|
{
|
||||||
|
cursor = branch;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reference.length () && cursor != this)
|
||||||
|
return cursor;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int DOM::Node::count () const
|
||||||
|
{
|
||||||
|
// Recurse and count the branches.
|
||||||
|
int total {0};
|
||||||
|
for (auto& branch : _branches)
|
||||||
|
{
|
||||||
|
if (branch->_provider)
|
||||||
|
++total;
|
||||||
|
total += branch->count ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::string DOM::Node::dumpNode (
|
||||||
|
const DOM::Node* node,
|
||||||
int depth) const
|
int depth) const
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
// Dump node
|
// Indent.
|
||||||
for (int i = 0; i < depth; ++i)
|
out << std::string (depth * 2, ' ');
|
||||||
out << " ";
|
|
||||||
|
|
||||||
out
|
out << "\033[31m" << node->_name << "\033[0m";
|
||||||
// Useful for debugging tree node new/delete errors.
|
|
||||||
// << std::hex << t << " "
|
if (node->_provider)
|
||||||
<< "\033[1m" << t->_name << "\033[0m\n";
|
out << " 0x" << std::hex << (long long) (void*) node->_provider;
|
||||||
|
|
||||||
|
out << '\n';
|
||||||
|
|
||||||
// Recurse for branches.
|
// Recurse for branches.
|
||||||
for (auto& b : t->_branches)
|
for (auto& b : node->_branches)
|
||||||
out << dumpNode (b, depth + 1);
|
out << dumpNode (b, depth + 1);
|
||||||
|
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string DOM::dump () const
|
std::string DOM::Node::dump () const
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
out << "DOM (" << count () << " nodes)\n"
|
out << "DOM::Node (" << count () << " nodes)\n"
|
||||||
<< dumpNode (std::make_shared <DOM> (*this), 1);
|
<< dumpNode (this, 1);
|
||||||
|
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
16
src/DOM.h
16
src/DOM.h
|
@ -41,10 +41,13 @@ public:
|
||||||
~DOM ();
|
~DOM ();
|
||||||
void addSource (const std::string&, bool (*)(const std::string&, Variant&));
|
void addSource (const std::string&, bool (*)(const std::string&, Variant&));
|
||||||
bool valid (const std::string&) const;
|
bool valid (const std::string&) const;
|
||||||
|
/*
|
||||||
|
// TODO Task object should register a generic provider.
|
||||||
Variant get (const Task&, const std::string&) const;
|
Variant get (const Task&, const std::string&) const;
|
||||||
|
*/
|
||||||
Variant get (const std::string&) const;
|
Variant get (const std::string&) const;
|
||||||
int count () const;
|
int count () const;
|
||||||
std::shared_ptr <DOM> find (const std::string&);
|
static std::vector <std::string> decomposeReference (const std::string&);
|
||||||
std::string dump () const;
|
std::string dump () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -52,6 +55,17 @@ private:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~Node ();
|
~Node ();
|
||||||
|
void addSource (const std::string&, bool (*)(const std::string&, Variant&));
|
||||||
|
bool valid (const std::string&) const;
|
||||||
|
const DOM::Node* find (const std::string&) const;
|
||||||
|
int count () const;
|
||||||
|
std::string dumpNode (const DOM::Node*, int) const;
|
||||||
|
std::string dump () const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string _name {"Unknown"};
|
||||||
|
bool (*_provider)(const std::string&, Variant&) {nullptr};
|
||||||
|
std::vector <DOM::Node*> _branches {};
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue