From d192d6cf91669f0638048e4d708712f39c345f8e Mon Sep 17 00:00:00 2001 From: falsycat Date: Fri, 10 Jun 2022 18:23:03 +0900 Subject: [PATCH] add nf7::GenericWatcher --- CMakeLists.txt | 1 + common/generic_watcher.hh | 30 ++++++++++++++++ file/luajit_obj.cc | 76 +++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 44 deletions(-) create mode 100644 common/generic_watcher.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index fab7e09..b41a57b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ target_sources(nf7 common/generic_history.hh common/generic_memento.hh common/generic_type_info.hh + common/generic_watcher.hh common/gui_file.hh common/gui_node.hh common/gui_window.hh diff --git a/common/generic_watcher.hh b/common/generic_watcher.hh new file mode 100644 index 0000000..311b3fa --- /dev/null +++ b/common/generic_watcher.hh @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include "nf7.hh" + + +namespace nf7 { + +class GenericWatcher final : public Env::Watcher { + public: + using Handler = std::function; + + GenericWatcher(Env& env) noexcept : Watcher(env) { + } + + void AddHandler(File::Event::Type type, Handler&& h) noexcept { + handlers_[type] = std::move(h); + } + void Handle(const File::Event& ev) noexcept override { + auto handler = handlers_.find(ev.type); + if (handler == handlers_.end()) return; + handler->second(ev); + } + + private: + std::unordered_map handlers_; +}; + +} // namespace nf7 diff --git a/file/luajit_obj.cc b/file/luajit_obj.cc index f10953e..d93b137 100644 --- a/file/luajit_obj.cc +++ b/file/luajit_obj.cc @@ -17,6 +17,7 @@ #include "common/future.hh" #include "common/generic_context.hh" #include "common/generic_type_info.hh" +#include "common/generic_watcher.hh" #include "common/lock.hh" #include "common/luajit.hh" #include "common/luajit_obj.hh" @@ -42,7 +43,6 @@ class Obj final : public nf7::File, static constexpr size_t kMaxSize = 1024*1024*16; /* = 16 MiB */ - class SrcWatcher; class ExecTask; Obj(Env& env, Path&& path = {}) noexcept : @@ -75,8 +75,8 @@ class Obj final : public nf7::File, private: std::shared_ptr log_; - std::unique_ptr srcwatcher_; - std::shared_ptr cache_; + std::optional watcher_; + std::shared_ptr cache_; nf7::Task>::Holder exec_; @@ -94,27 +94,6 @@ class Obj final : public nf7::File, void Reset() noexcept; }; -class Obj::SrcWatcher final : public nf7::Env::Watcher { - public: - SrcWatcher(Obj& owner, File::Id id) : - Watcher(owner.env()), owner_(&owner) { - if (owner.id() == id) throw Exception("self watch"); - if (id == 0) throw Exception("invalid id"); - Watch(id); - } - - void Handle(const File::Event& ev) noexcept override { - if (ev.type == File::Event::kUpdate) { - owner_->log_->Info("detected update of source file, drops cache automatically"); - owner_->cache_ = nullptr; - owner_->Touch(); - } - } - - private: - Obj* const owner_; -}; - class Obj::ExecTask final : public nf7::Task> { public: ExecTask(Obj& target) noexcept : @@ -175,9 +154,28 @@ class Obj::ExecTask final : public nf7::Task> return luaL_ref(L, LUA_REGISTRYINDEX); }); - // context for luajit script running - auto lua_ctx = std::make_shared(env(), initiator()); - lua_ctx->description() = "luajit object build script runner"; + // setup watcher + try { + *target_->src_; // check if the src is alive + + auto& w = target_->watcher_; + w.emplace(env()); + w->Watch(srcf.id()); + + std::weak_ptr wself = self(); + w->AddHandler(Event::kUpdate, [t = target_, wself](auto&) { + if (auto self = wself.lock()) { + t->log_->Info("detected update of source file, aborts building"); + t->exec_ = {}; + } else if (t->cache_) { + t->log_->Info("detected update of source file, drops cache automatically"); + t->cache_ = nullptr; + t->Touch(); + } + }); + } catch (Exception& e) { + log_->Warn("watcher setup error: "+e.msg()); + } // queue task to trigger the thread auto ljq = target_-> @@ -242,18 +240,12 @@ nf7::Future> Obj::Build() noexcept { void Obj::Handle(const Event& ev) noexcept { switch (ev.type) { case Event::kAdd: - try { - log_->SetUp(*this); - auto ctx = std::make_shared(env(), id()); - ctx->description() = "resetting state"; - env().ExecMain(ctx, [this]() { Reset(); }); - } catch (Exception&) { - } + log_->SetUp(*this); break; case Event::kRemove: - exec_ = {}; - cache_ = nullptr; - srcwatcher_ = nullptr; + exec_ = {}; + cache_ = nullptr; + watcher_ = std::nullopt; log_->TearDown(); break; @@ -262,13 +254,9 @@ void Obj::Handle(const Event& ev) noexcept { } } void Obj::Reset() noexcept { - exec_ = {}; - cache_ = nullptr; - try { - srcwatcher_ = std::make_unique(*this, src_.id()); - } catch (Exception&) { - srcwatcher_ = nullptr; - } + exec_ = {}; + cache_ = nullptr; + watcher_ = std::nullopt; } void Obj::Update() noexcept {