remove nf7::FileHolder

This commit is contained in:
falsycat 2022-11-06 11:13:07 +09:00
parent 3e2d162d65
commit b463e112aa
8 changed files with 195 additions and 99 deletions

View File

@ -85,6 +85,8 @@ target_sources(nf7
common/gl_obj.hh
common/gl_obj.cc
common/gl_shader_preproc.hh
common/gui.hh
common/gui.cc
common/gui_config.hh
common/gui_context.hh
common/gui_dnd.hh

72
common/gui.cc Normal file
View File

@ -0,0 +1,72 @@
#include "common/gui.hh"
#include <optional>
#include <string>
#include <imgui.h>
#include <imgui_stdlib.h>
#include "nf7.hh"
#include "common/gui_dnd.hh"
namespace nf7::gui {
bool PathButton(const char* id, nf7::File::Path& p, nf7::File&) noexcept {
bool ret = false;
const auto w = ImGui::CalcItemWidth();
ImGui::PushID(id);
const auto pstr = p.Stringify();
if (ImGui::Button(pstr.c_str(), {w, 0})) {
ImGui::OpenPopup("editor");
}
if (ImGui::BeginDragDropTarget()) {
if (auto dp = nf7::gui::dnd::Accept<nf7::File::Path>(nf7::gui::dnd::kFilePath)) {
p = std::move(*dp);
ret = true;
}
ImGui::EndDragDropTarget();
}
ImGui::SameLine();
ImGui::TextUnformatted(id);
if (ImGui::BeginPopup("editor")) {
static std::string editing_str;
if (ImGui::IsWindowAppearing()) {
editing_str = pstr;
}
bool submit = false;
if (ImGui::InputText("path", &editing_str, ImGuiInputTextFlags_EnterReturnsTrue)) {
submit = true;
}
std::optional<nf7::File::Path> newpath;
try {
newpath = nf7::File::Path::Parse(editing_str);
} catch (nf7::Exception& e) {
ImGui::Text("invalid path: %s", e.msg().c_str());
}
ImGui::BeginDisabled(!newpath);
if (ImGui::Button("ok")) {
submit = true;
}
ImGui::EndDisabled();
if (newpath && submit) {
ImGui::CloseCurrentPopup();
p = std::move(*newpath);
ret = true;
}
ImGui::EndPopup();
}
ImGui::PopID();
return ret;
}
} // namespace nf7::gui

10
common/gui.hh Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include "nf7.hh"
namespace nf7::gui {
bool PathButton(const char* id, nf7::File::Path&, nf7::File&) noexcept;
} // namespace nf7::gui

View File

@ -40,6 +40,8 @@ void Config(nf7::GenericMemento<T>& mem) noexcept {
mod_ = false;
} catch (nf7::Exception& e) {
msg_ = e.msg();
} catch (std::exception& e) {
msg_ = e.what();
}
}
ImGui::EndDisabled();

View File

@ -15,11 +15,10 @@
#include <yas/types/std/vector.hpp>
#include "common/file_base.hh"
#include "common/file_holder.hh"
#include "common/generic_context.hh"
#include "common/generic_memento.hh"
#include "common/generic_type_info.hh"
#include "common/gui_file.hh"
#include "common/gui.hh"
#include "common/gui_value.hh"
#include "common/life.hh"
#include "common/ptr_selector.hh"
@ -55,35 +54,32 @@ class Adaptor final : public nf7::FileBase, public nf7::Sequencer {
}
};
struct Data {
nf7::FileHolder::Tag target;
nf7::File::Path path;
std::vector<std::pair<std::string, nf7::gui::Value>> input_imm;
std::vector<std::pair<std::string, Var>> input_map;
std::vector<std::pair<std::string, std::string>> output_map;
void serialize(auto& ar) {
ar(path, input_imm, input_map, output_map);
}
};
Adaptor(nf7::Env& env, Data&& data = {}) noexcept :
Adaptor(nf7::Env& env, Data&& d = {}) noexcept :
nf7::FileBase(kType, env),
Sequencer(Sequencer::kCustomItem |
Sequencer::kTooltip |
Sequencer::kParamPanel),
life_(*this),
target_(*this, "target", mem_),
target_editor_(*this, target_,
[](auto& t) { return t.flags().contains("nf7::Sequencer"); }),
mem_(std::move(data), *this) {
mem_.data().target.SetTarget(target_);
mem_.CommitAmend();
life_(*this), mem_(std::move(d), *this) {
}
Adaptor(nf7::Deserializer& ar) : Adaptor(ar.env()) {
ar(target_, data().input_imm, data().input_map, data().output_map);
ar(mem_.data());
}
void Serialize(nf7::Serializer& ar) const noexcept override {
ar(target_, data().input_imm, data().input_map, data().output_map);
ar(mem_.data());
}
std::unique_ptr<nf7::File> Clone(nf7::Env& env) const noexcept override {
return std::make_unique<Adaptor>(env, Data {data()});
return std::make_unique<Adaptor>(env, Data {mem_.data()});
}
std::shared_ptr<nf7::Sequencer::Lambda> CreateLambda(
@ -100,14 +96,8 @@ class Adaptor final : public nf7::FileBase, public nf7::Sequencer {
private:
nf7::Life<Adaptor> life_;
nf7::FileHolder target_;
nf7::gui::FileHolderEditor target_editor_;
nf7::GenericMemento<Data> mem_;
const Data& data() const noexcept { return mem_.data(); }
Data& data() noexcept { return mem_.data(); }
};
@ -115,10 +105,10 @@ class Adaptor::Session final : public nf7::Sequencer::Session {
public:
// ensure that Adaptor is alive
Session(Adaptor& f, const std::shared_ptr<nf7::Sequencer::Session>& parent) noexcept : parent_(parent) {
for (auto& p : f.data().input_imm) {
for (auto& p : f.mem_->input_imm) {
vars_[p.first] = p.second.entity();
}
for (auto& p : f.data().input_map) {
for (auto& p : f.mem_->input_map) {
if (p.second.name.size() == 0) continue;
if (p.second.peek) {
if (const auto ptr = parent->Peek(p.second.name)) {
@ -130,7 +120,7 @@ class Adaptor::Session final : public nf7::Sequencer::Session {
}
}
}
for (auto& p : f.data().output_map) {
for (auto& p : f.mem_->output_map) {
outs_[p.first] = p.second;
}
}
@ -183,7 +173,7 @@ class Adaptor::Lambda final : public nf7::Sequencer::Lambda,
try {
f_.EnforceAlive();
auto& target = f_->target_.GetFileOrThrow();
auto& target = f_->ResolveOrThrow(f_->mem_->path);
auto& seq = target.interfaceOrThrow<nf7::Sequencer>();
if (!la_ || target.id() != cached_id_) {
la_ = seq.CreateLambda(shared_from_this());
@ -214,25 +204,29 @@ class Adaptor::Editor final : public nf7::Sequencer::Editor {
void Adaptor::UpdateItem(Sequencer::Editor&) noexcept {
try {
auto& seq = target_.GetFileOrThrow().interfaceOrThrow<nf7::Sequencer>();
auto& seq = ResolveOrThrow(mem_->path).interfaceOrThrow<nf7::Sequencer>();
if (seq.flags() & nf7::Sequencer::kCustomItem) {
Adaptor::Editor ed;
seq.UpdateItem(ed);
}
} catch (nf7::Exception&) {
ImGui::Text("%s", target_editor_.GetDisplayText().c_str());
} catch (nf7::File::NotFoundException&) {
ImGui::TextUnformatted("file missing");
} catch (nf7::File::NotImplementedException&) {
ImGui::TextUnformatted("file does not have Sequencer interface");
}
}
void Adaptor::UpdateParamPanel(Sequencer::Editor&) noexcept {
bool commit = false;
auto& imm = data().input_imm;
auto& inputs = data().input_map;
auto& outputs = data().output_map;
auto& imm = mem_->input_imm;
auto& inputs = mem_->input_map;
auto& outputs = mem_->output_map;
const auto em = ImGui::GetFontSize();
if (ImGui::CollapsingHeader("Sequencer/Adaptor", ImGuiTreeNodeFlags_DefaultOpen)) {
target_editor_.ButtonWithLabel("target");
if (nf7::gui::PathButton("path", mem_->path, *this)) {
commit = true;
}
if (ImGui::BeginTable("table", 3)) {
ImGui::TableSetupColumn("left", ImGuiTableColumnFlags_WidthStretch, 1.f);
@ -389,7 +383,7 @@ void Adaptor::UpdateParamPanel(Sequencer::Editor&) noexcept {
ImGui::Spacing();
try {
auto& seq = target_.GetFileOrThrow().interfaceOrThrow<nf7::Sequencer>();
auto& seq = ResolveOrThrow(mem_->path).interfaceOrThrow<nf7::Sequencer>();
if (seq.flags() & nf7::Sequencer::kParamPanel) {
Adaptor::Editor ed;
seq.UpdateParamPanel(ed);
@ -405,4 +399,3 @@ void Adaptor::UpdateTooltip(Sequencer::Editor&) noexcept {
}
} // namespace nf7

View File

@ -12,7 +12,7 @@
#include <yas/types/std/vector.hpp>
#include "common/file_base.hh"
#include "common/file_holder.hh"
#include "common/gui.hh"
#include "common/generic_context.hh"
#include "common/generic_memento.hh"
#include "common/generic_type_info.hh"
@ -42,9 +42,13 @@ class Call final : public nf7::FileBase, public nf7::Sequencer {
class SessionLambda;
struct Data {
nf7::FileHolder::Tag callee;
std::string expects;
bool pure;
nf7::File::Path callee;
std::string expects;
bool pure;
void serialize(auto& ar) {
ar(callee, expects, pure);
}
};
Call(nf7::Env& env, Data&& data = {}) noexcept :
@ -53,22 +57,17 @@ class Call final : public nf7::FileBase, public nf7::Sequencer {
Sequencer::kTooltip |
Sequencer::kParamPanel),
life_(*this),
callee_(*this, "callee", mem_),
callee_editor_(*this, callee_,
[](auto& t) { return t.flags().contains("nf7::Node"); }),
mem_(std::move(data), *this) {
mem_.data().callee.SetTarget(callee_);
mem_.CommitAmend();
}
Call(nf7::Deserializer& ar) : Call(ar.env()) {
ar(callee_, data().expects, data().pure);
ar(mem_.data());
}
void Serialize(nf7::Serializer& ar) const noexcept override {
ar(callee_, data().expects, data().pure);
ar(mem_.data());
}
std::unique_ptr<nf7::File> Clone(nf7::Env& env) const noexcept override {
return std::make_unique<Call>(env, Data {data()});
return std::make_unique<Call>(env, Data {mem_.data()});
}
std::shared_ptr<nf7::Sequencer::Lambda> CreateLambda(
@ -79,20 +78,14 @@ class Call final : public nf7::FileBase, public nf7::Sequencer {
void UpdateTooltip(nf7::Sequencer::Editor&) noexcept override;
nf7::File::Interface* interface(const std::type_info& t) noexcept override {
return InterfaceSelector<
return nf7::InterfaceSelector<
nf7::Memento, nf7::Sequencer>(t).Select(this, &mem_);
}
private:
nf7::Life<Call> life_;
nf7::FileHolder callee_;
nf7::gui::FileHolderEditor callee_editor_;
nf7::GenericMemento<Data> mem_;
Data& data() noexcept { return mem_.data(); }
const Data& data() const noexcept { return mem_.data(); }
};
@ -126,7 +119,7 @@ class Call::SessionLambda final : public nf7::Node::Lambda {
assert(!ss_);
ss_ = ss;
const auto ex = f.data().expects;
const auto ex = f.mem_->expects;
size_t begin = 0;
for (size_t i = 0; i <= ex.size(); ++i) {
if (i == ex.size() || ex[i] == '\n') {
@ -174,8 +167,8 @@ try {
if (abort_) return;
file_.EnforceAlive();
auto& data = file_->data();
auto& callee = file_->callee_.GetFileOrThrow();
auto& data = file_->mem_.data();
auto& callee = file_->ResolveOrThrow(data.callee);
auto& node = callee.interfaceOrThrow<nf7::Node>();
if (!ssla_) {
@ -218,30 +211,35 @@ void Call::Lambda::Abort() noexcept {
void Call::UpdateItem(Sequencer::Editor&) noexcept {
ImGui::Text("%s", callee_editor_.GetDisplayText().c_str());
ImGui::Text("%s", mem_->callee.Stringify().c_str());
}
void Call::UpdateParamPanel(Sequencer::Editor&) noexcept {
const auto em = ImGui::GetFontSize();
bool commit = false;
if (ImGui::CollapsingHeader("Sequencer/Call", ImGuiTreeNodeFlags_DefaultOpen)) {
callee_editor_.ButtonWithLabel("callee");
if (nf7::gui::PathButton("callee", mem_->callee, *this)) {
commit = true;
}
ImGui::InputTextMultiline("expects", &data().expects, {0, 4.f*em});
ImGui::InputTextMultiline("expects", &mem_->expects, {0, 4.f*em});
if (ImGui::IsItemDeactivatedAfterEdit()) {
mem_.Commit();
commit = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("session ends right after receiving these outputs");
}
if (ImGui::Checkbox("pure", &data().pure)) {
mem_.Commit();
if (ImGui::Checkbox("pure", &mem_->pure)) {
commit = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("callee's lambda is created for each session");
}
ImGui::Spacing();
callee_editor_.ItemWidget("callee");
}
if (commit) {
mem_.Commit();
}
}
void Call::UpdateTooltip(Sequencer::Editor&) noexcept {

View File

@ -8,12 +8,16 @@
#include <imgui.h>
#include <yaml-cpp/yaml.h>
#include <yas/serialize.hpp>
#include "nf7.hh"
#include "common/dir_item.hh"
#include "common/file_base.hh"
#include "common/file_holder.hh"
#include "common/gui_file.hh"
#include "common/gui.hh"
#include "common/gui_config.hh"
#include "common/generic_context.hh"
#include "common/generic_memento.hh"
#include "common/generic_type_info.hh"
@ -23,6 +27,7 @@
#include "common/node.hh"
#include "common/ptr_selector.hh"
#include "common/value.hh"
#include "common/yas_nf7.hh"
namespace nf7 {
@ -39,31 +44,48 @@ class Event final : public nf7::FileBase, public nf7::DirItem, public nf7::Node
class Lambda;
struct Data final {
nf7::FileHolder::Tag handler;
struct Data {
nf7::File::Path handler;
void serialize(auto& ar) {
ar(handler);
}
std::string Stringify() const noexcept {
YAML::Emitter st;
st << YAML::BeginMap;
st << YAML::Key << "handler";
st << YAML::Value << handler.Stringify();
st << YAML::EndMap;
return {st.c_str(), st.size()};
}
void Parse(const std::string& str) {
const auto yaml = YAML::Load(str);
Data d;
d.handler = nf7::File::Path::Parse(yaml["handler"].as<std::string>());
*this = std::move(d);
}
};
Event(nf7::Env& env, Data&& data = {}) noexcept :
Event(nf7::Env& env, Data&& d = {}) noexcept :
nf7::FileBase(kType, env),
nf7::DirItem(nf7::DirItem::kMenu | nf7::DirItem::kWidget),
nf7::DirItem(nf7::DirItem::kMenu),
nf7::Node(nf7::Node::kMenu_DirItem),
life_(*this), logger_(*this),
handler_(*this, "handler", mem_),
handler_editor_(*this, handler_,
[](auto& t) { return t.flags().contains("nf7::Node"); }),
life_(*this), log_(*this),
la_root_(std::make_shared<nf7::Node::Lambda>(*this)),
mem_(std::move(data)) {
handler_.onEmplace = [this]() { la_ = nullptr; };
mem_(std::move(d), *this) {
}
Event(nf7::Deserializer& ar) : Event(ar.env()) {
ar(handler_);
ar(mem_.data());
}
void Serialize(nf7::Serializer& ar) const noexcept override {
ar(handler_);
ar(mem_.data());
}
std::unique_ptr<nf7::File> Clone(nf7::Env& env) const noexcept override {
return std::make_unique<Event>(env, Data {data()});
return std::make_unique<Event>(env, Data {mem_.data()});
}
std::shared_ptr<nf7::Node::Lambda> CreateLambda(
@ -78,7 +100,6 @@ class Event final : public nf7::FileBase, public nf7::DirItem, public nf7::Node
void Update() noexcept override;
void UpdateMenu() noexcept override;
void UpdateWidget() noexcept override;
nf7::File::Interface* interface(const std::type_info& t) noexcept override {
return nf7::InterfaceSelector<nf7::DirItem, nf7::Node>(t).Select(this);
@ -86,35 +107,31 @@ class Event final : public nf7::FileBase, public nf7::DirItem, public nf7::Node
private:
nf7::Life<Event> life_;
nf7::LoggerRef logger_;
nf7::FileHolder handler_;
nf7::gui::FileHolderEditor handler_editor_;
nf7::LoggerRef log_;
std::shared_ptr<nf7::Node::Lambda> la_root_;
std::shared_ptr<nf7::Node::Lambda> la_;
nf7::GenericMemento<Data> mem_;
Data& data() noexcept { return mem_.data(); }
const Data& data() const noexcept { return mem_.data(); }
std::span<const std::string> GetHandlerInputs() noexcept
nf7::Node& GetHandler() const {
return ResolveOrThrow(mem_->handler).interfaceOrThrow<nf7::Node>();
}
std::span<const std::string> GetHandlerInputs() const noexcept
try {
return handler_.GetFileOrThrow().interfaceOrThrow<nf7::Node>().GetInputs();
return GetHandler().GetInputs();
} catch (nf7::Exception&) {
return {};
}
std::shared_ptr<nf7::Node::Lambda> CreateLambdaIf() noexcept {
try {
if (!la_) {
auto& n = handler_.GetFileOrThrow().interfaceOrThrow<nf7::Node>();
la_ = n.CreateLambda(la_root_);
la_ = GetHandler().CreateLambda(la_root_);
}
return la_;
} catch (nf7::Exception& e) {
logger_.Warn("failed to create handler's lambda: "+e.msg());
log_.Warn("failed to create handler's lambda: "+e.msg());
la_ = nullptr;
return nullptr;
}
@ -184,13 +201,11 @@ void Event::UpdateMenu() noexcept {
if (ImGui::MenuItem("drop handler's lambda")) {
la_ = nullptr;
}
}
void Event::UpdateWidget() noexcept {
ImGui::TextUnformatted("System/Event");
handler_editor_.ButtonWithLabel("handler");
handler_editor_.ItemWidget("handler");
handler_editor_.Update();
ImGui::Separator();
if (ImGui::BeginMenu("config")) {
nf7::gui::Config(mem_);
ImGui::EndMenu();
}
}
} // namespace

4
nf7.cc
View File

@ -120,6 +120,10 @@ File& File::ResolveOrThrow(const Path& p) const
try {
assert(id_ != 0);
if (p.terms().empty()) {
throw nf7::Exception {"empty path"};
}
auto ret = const_cast<File*>(this);
for (const auto& term : p.terms()) {
if (term == "..") {