improve nf7::Env::Watcher interface

This commit is contained in:
2022-11-09 11:29:31 +09:00
parent 7a2ead6e6f
commit c02d9e3b10
3 changed files with 36 additions and 16 deletions

27
main.cc
View File

@@ -214,14 +214,16 @@ class Env final : public nf7::Env {
f.Handle(e);
// trigger file watcher
auto itr = watchers_map_.find(e.id);
if (itr != watchers_map_.end()) {
auto itr = watchers_.find(e.id);
if (itr != watchers_.end()) {
for (auto w : itr->second) w->Handle(e);
}
// trigger global watcher
for (auto w : watchers_map_[0]) w->Handle(e);
itr = watchers_.find(0);
if (itr != watchers_.end()) {
for (auto w : itr->second) w->Handle(e);
}
return &f;
} catch (nf7::ExpiredException&) {
return nullptr;
@@ -269,15 +271,17 @@ class Env final : public nf7::Env {
}
void AddWatcher(nf7::File::Id id, nf7::Env::Watcher& w) noexcept override {
watchers_map_[id].push_back(&w);
watchers_rmap_[&w].push_back(id);
watchers_[id].push_back(&w);
}
void RemoveWatcher(nf7::Env::Watcher& w) noexcept override {
for (const auto id : watchers_rmap_[&w]) {
auto& v = watchers_map_[id];
void RemoveWatcher(nf7::File::Id id, nf7::Env::Watcher& w) noexcept override {
auto itr = watchers_.find(id);
if (watchers_.end() != itr) {
auto& v = itr->second;
v.erase(std::remove(v.begin(), v.end(), &w), v.end());
if (v.size() == 0) {
watchers_.erase(itr);
}
}
watchers_rmap_.erase(&w);
}
private:
@@ -288,8 +292,7 @@ class Env final : public nf7::Env {
nf7::File::Id file_next_ = 1;
std::unordered_map<nf7::File::Id, nf7::File*> files_;
std::unordered_map<nf7::File::Id, std::vector<nf7::Env::Watcher*>> watchers_map_;
std::unordered_map<nf7::Env::Watcher*, std::vector<nf7::File::Id>> watchers_rmap_;
std::unordered_map<nf7::File::Id, std::vector<nf7::Env::Watcher*>> watchers_;
};

16
nf7.cc
View File

@@ -265,10 +265,22 @@ File& Env::GetFileOrThrow(File::Id id) const {
Env::Watcher::Watcher(Env& env) noexcept : env_(&env) {
}
Env::Watcher::~Watcher() noexcept {
env_->RemoveWatcher(*this);
for (auto id : targets_) {
env_->RemoveWatcher(id, *this);
}
}
void Env::Watcher::Watch(File::Id id) noexcept {
env_->AddWatcher(id, *this);
if (targets_.end() == std::find(targets_.begin(), targets_.end(), id)) {
targets_.push_back(id);
env_->AddWatcher(id, *this);
}
}
void Env::Watcher::Unwatch(File::Id id) noexcept {
auto itr = std::remove(targets_.begin(), targets_.end(), id);
if (itr != targets_.end()) {
targets_.erase(itr);
env_->RemoveWatcher(id, *this);
}
}

9
nf7.hh
View File

@@ -302,7 +302,7 @@ class Env {
virtual void RemoveFile(File::Id) noexcept = 0;
virtual void AddWatcher(File::Id, Watcher&) noexcept = 0;
virtual void RemoveWatcher(Watcher&) noexcept = 0;
virtual void RemoveWatcher(File::Id, Watcher&) noexcept = 0;
private:
std::filesystem::path npath_;
@@ -316,12 +316,17 @@ class Env::Watcher {
Watcher& operator=(const Watcher&) = delete;
Watcher& operator=(Watcher&&) = delete;
void Watch(File::Id) noexcept;
void Unwatch(File::Id) noexcept;
virtual void Handle(const File::Event&) noexcept = 0;
void Watch(File::Id) noexcept;
const std::vector<File::Id>& targets() const noexcept { return targets_; }
private:
Env* const env_;
std::vector<File::Id> targets_;
};