add System/Call

This commit is contained in:
falsycat 2022-08-27 12:40:51 +09:00
parent 0c4454f623
commit a93787b43b
4 changed files with 141 additions and 2 deletions

View File

@ -117,6 +117,7 @@ target_sources(nf7
file/sequencer_adaptor.cc
file/sequencer_call.cc
file/sequencer_timeline.cc
file/system_call.cc
file/system_dir.cc
file/system_imgui.cc
file/system_logger.cc

129
file/system_call.cc Normal file
View File

@ -0,0 +1,129 @@
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include <imgui.h>
#include <ImNodes.h>
#include "nf7.hh"
#include "common/generic_context.hh"
#include "common/generic_type_info.hh"
#include "common/gui_node.hh"
#include "common/node.hh"
#include "common/ptr_selector.hh"
#include "common/yas_std_atomic.hh"
using namespace std::literals;
namespace nf7 {
namespace {
class Call final : public nf7::File, public nf7::Node {
public:
static inline const nf7::GenericTypeInfo<Call> kType = {
"System/Call", {"nf7::Node"}};
static void UpdateTypeTooltip() noexcept {
ImGui::TextUnformatted("Call system features.");
ImGui::Bullet(); ImGui::TextUnformatted("implements nf7::Node");
}
class Lambda;
Call(nf7::Env& env) noexcept :
nf7::File(kType, env),
nf7::Node(nf7::Node::kCustomNode) {
}
Call(nf7::Deserializer& ar) : Call(ar.env()) {
}
void Serialize(nf7::Serializer&) const noexcept override {
}
std::unique_ptr<nf7::File> Clone(nf7::Env& env) const noexcept override {
return std::make_unique<Call>(env);
}
std::shared_ptr<nf7::Node::Lambda> CreateLambda(
const std::shared_ptr<nf7::Node::Lambda>&) noexcept override;
std::span<const std::string> GetInputs() const noexcept override {
static const std::vector<std::string> kInputs = {"save", "exit", "abort", "panic"};
return kInputs;
}
std::span<const std::string> GetOutputs() const noexcept override {
return {};
}
void UpdateNode(nf7::Node::Editor&) noexcept override;
nf7::File::Interface* interface(const std::type_info& t) noexcept override {
return nf7::InterfaceSelector<nf7::Node>(t).Select(this);
}
};
class Call::Lambda final : public nf7::Node::Lambda,
public std::enable_shared_from_this<Call::Lambda> {
public:
Lambda(Call& f, const std::shared_ptr<nf7::Node::Lambda>& parent) noexcept :
nf7::Node::Lambda(f, parent) {
}
void Handle(std::string_view name, const nf7::Value& v,
const std::shared_ptr<nf7::Node::Lambda>&) noexcept override {
if (name == "save") {
env().ExecMain(shared_from_this(), [this]() {
env().Save();
});
} else if (name == "exit") {
env().Exit();
} else if (name == "abort") {
std::abort();
} else if (name == "panic") {
try {
if (v.isString()) {
throw nf7::Exception {v.string()};
} else {
throw nf7::Exception {
"'panic' input can take a string as message shown here :)"};
}
} catch (nf7::Exception&) {
env().Throw(std::make_exception_ptr<nf7::Exception>({"panic caused by System/Call"}));
}
}
}
};
std::shared_ptr<nf7::Node::Lambda> Call::CreateLambda(
const std::shared_ptr<nf7::Node::Lambda>& parent) noexcept {
return std::make_shared<Call::Lambda>(*this, parent);
}
void Call::UpdateNode(nf7::Node::Editor&) noexcept {
ImGui::TextUnformatted("System/Call");
static const std::vector<std::pair<std::string, std::string>> kSockets = {
{"save", "save entire nf7 system when get any value"},
{"exit", "exit nf7 after saving when get any value"},
{"abort", "[DANGER] abort nf7 process WITHOUT SAVING when get any value"},
{"panic", "take a string message and make a panic to notify user"},
};
for (auto& sock : kSockets) {
if (ImNodes::BeginInputSlot(sock.first.c_str(), 1)) {
nf7::gui::NodeSocket();
ImGui::SameLine();
ImGui::TextUnformatted(sock.first.c_str());
ImNodes::EndSlot();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(sock.second.c_str());
}
}
}
} // namespace
} // namespace nf7

10
main.cc
View File

@ -99,6 +99,9 @@ class Env final : public nf7::Env {
} catch (ExpiredException&) {
}
void Exit() noexcept override {
exit_requested_ = true;
}
void Save() noexcept override {
try {
nf7::Serializer::Save(kFileName, root_);
@ -129,6 +132,8 @@ class Env final : public nf7::Env {
cv_.notify_one();
}
bool exitRequested() const noexcept { return exit_requested_; }
protected:
File* GetFile(File::Id id) const noexcept override {
auto itr = files_.find(id);
@ -158,6 +163,7 @@ class Env final : public nf7::Env {
private:
std::unique_ptr<File> root_;
std::atomic<bool> exit_requested_ = false;
std::atomic<bool> alive_ = true;
std::exception_ptr panic_;
@ -185,7 +191,7 @@ class Env final : public nf7::Env {
void UpdatePanic() noexcept {
const auto em = ImGui::GetFontSize();
ImGui::SetNextWindowSize({16*em, 12*em}, ImGuiCond_Appearing);
ImGui::SetNextWindowSize({32*em, 24*em}, ImGuiCond_Appearing);
if (ImGui::BeginPopupModal("panic")) {
ImGui::TextUnformatted("something went wrong X(");
@ -315,7 +321,7 @@ int main(int, char**) {
{
::Env env;
glfwShowWindow(window);
while (!glfwWindowShouldClose(window)) {
while (!glfwWindowShouldClose(window) && !env.exitRequested()) {
// new frame
glfwPollEvents();
ImGui_ImplOpenGL3_NewFrame();

3
nf7.hh
View File

@ -273,6 +273,9 @@ class Env {
virtual void Handle(const File::Event&) noexcept = 0;
// thread-safe
virtual void Exit() noexcept = 0;
virtual void Save() noexcept = 0;
virtual void Throw(std::exception_ptr&&) noexcept = 0;