C++ NetworkTable: Provide AddSubTableListener().

This matches the implementation provided by Java NetworkTable, with the
exception that the subtable is not provided (because it's not a value).
The listener still can get access to the subtable by calling
source->getSubTable(key).
This commit is contained in:
Peter Johnson
2015-09-19 12:18:25 -07:00
parent a3effbfb9f
commit 4c83259acb
3 changed files with 35 additions and 0 deletions

View File

@@ -3,6 +3,7 @@
#include <algorithm>
#include "llvm/SmallString.h"
#include "llvm/StringMap.h"
#include "tables/ITableListener.h"
#include "ntcore.h"
@@ -136,6 +137,33 @@ void NetworkTable::AddTableListener(StringRef key,
m_listeners.emplace_back(listener, id);
}
void NetworkTable::AddSubTableListener(ITableListener* listener) {
std::lock_guard<std::mutex> lock(m_mutex);
llvm::SmallString<128> path(m_path);
path += PATH_SEPARATOR_CHAR;
std::size_t prefix_len = path.size();
// The lambda needs to be copyable, but StringMap is not, so use
// a shared_ptr to it.
auto notified_tables = std::make_shared<llvm::StringMap<char>>();
unsigned int id = nt::AddEntryListener(
path,
[=](unsigned int uid, StringRef name, std::shared_ptr<nt::Value> value,
bool is_new) mutable {
StringRef relative_key = name.substr(prefix_len);
auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR);
if (end_sub_table == StringRef::npos) return;
StringRef sub_table_key = relative_key.substr(0, end_sub_table);
if (notified_tables->find(sub_table_key) == notified_tables->end())
return;
notified_tables->insert(std::make_pair(sub_table_key, '\0'));
listener->ValueChanged(this, sub_table_key, nullptr, true);
},
true);
m_listeners.emplace_back(listener, id);
}
void NetworkTable::RemoveTableListener(ITableListener* listener) {
std::lock_guard<std::mutex> lock(m_mutex);
auto matches_begin =