rename System/Call to System/Node and improve file structure
This commit is contained in:
parent
5d79d7631b
commit
e283e99276
@ -150,12 +150,12 @@ 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_event.cc
|
||||
file/system_imgui.cc
|
||||
file/system_logger.cc
|
||||
file/system_nfile.cc
|
||||
file/system_node.cc
|
||||
file/value_curve.cc
|
||||
file/value_plot.cc
|
||||
)
|
||||
|
@ -30,17 +30,19 @@ class GenericTypeInfo : public nf7::File::TypeInfo {
|
||||
|
||||
std::unique_ptr<nf7::File> Deserialize(nf7::Deserializer& ar) const override
|
||||
try {
|
||||
return std::make_unique<T>(ar);
|
||||
} catch (nf7::Exception&) {
|
||||
throw nf7::DeserializeException {"deserialization failed"};
|
||||
if constexpr (std::is_constructible<T, nf7::Deserializer&>::value) {
|
||||
return std::make_unique<T>(ar);
|
||||
} else {
|
||||
throw nf7::Exception {name() + " is not a deserializable"};
|
||||
}
|
||||
} catch (std::exception&) {
|
||||
throw nf7::DeserializeException {"deserialization failed"};
|
||||
throw nf7::DeserializeException {"deserialization failed ("+name()+")"};
|
||||
}
|
||||
std::unique_ptr<File> Create(nf7::Env& env) const override {
|
||||
if constexpr (std::is_constructible<T, nf7::Env&>::value) {
|
||||
return std::make_unique<T>(env);
|
||||
} else {
|
||||
throw nf7::Exception {name()+" has no factory without parameters"};
|
||||
throw nf7::Exception {name()+" has no default factory"};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,124 +0,0 @@
|
||||
#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.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;
|
||||
nf7::Node::Meta GetMeta() const noexcept override {
|
||||
return {{"save", "exit", "abort", "panic"}, {}};
|
||||
}
|
||||
|
||||
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(const nf7::Node::Lambda::Msg& in) noexcept override {
|
||||
if (in.name == "save") {
|
||||
env().ExecMain(shared_from_this(), [this]() {
|
||||
env().Save();
|
||||
});
|
||||
} else if (in.name == "exit") {
|
||||
env().Exit();
|
||||
} else if (in.name == "abort") {
|
||||
std::abort();
|
||||
} else if (in.name == "panic") {
|
||||
try {
|
||||
if (in.value.isString()) {
|
||||
throw nf7::Exception {in.value.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
|
191
file/system_node.cc
Normal file
191
file/system_node.cc
Normal file
@ -0,0 +1,191 @@
|
||||
#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/dir_item.hh"
|
||||
#include "common/file_base.hh"
|
||||
#include "common/generic_context.hh"
|
||||
#include "common/generic_dir.hh"
|
||||
#include "common/generic_type_info.hh"
|
||||
#include "common/gui.hh"
|
||||
#include "common/gui_dnd.hh"
|
||||
#include "common/node.hh"
|
||||
#include "common/ptr_selector.hh"
|
||||
#include "common/yas_std_atomic.hh"
|
||||
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace nf7 {
|
||||
namespace {
|
||||
|
||||
class SysNode final : public nf7::FileBase, public nf7::DirItem {
|
||||
public:
|
||||
static inline const nf7::GenericTypeInfo<SysNode> kType = {
|
||||
"System/Node", {}};
|
||||
static void UpdateTypeTooltip() noexcept {
|
||||
ImGui::TextUnformatted("Node system features.");
|
||||
ImGui::Bullet(); ImGui::TextUnformatted("implements nf7::Node");
|
||||
}
|
||||
|
||||
template <typename T> class NodeFile;
|
||||
class Save;
|
||||
class Exit;
|
||||
class Panic;
|
||||
|
||||
SysNode(nf7::Env& env) noexcept :
|
||||
nf7::FileBase(kType, env),
|
||||
nf7::DirItem(nf7::DirItem::kTree |
|
||||
nf7::DirItem::kImportant),
|
||||
dir_(*this, CreateItems(env)) {
|
||||
}
|
||||
|
||||
SysNode(nf7::Deserializer& ar) : SysNode(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<SysNode>(env);
|
||||
}
|
||||
|
||||
void UpdateTree() noexcept override;
|
||||
|
||||
nf7::File::Interface* interface(const std::type_info& t) noexcept override {
|
||||
return nf7::InterfaceSelector<nf7::DirItem>(t).Select(this);
|
||||
}
|
||||
|
||||
private:
|
||||
nf7::GenericDir dir_;
|
||||
|
||||
static nf7::GenericDir::ItemMap CreateItems(nf7::Env& env) noexcept {
|
||||
nf7::GenericDir::ItemMap items;
|
||||
items["save"] = CreateItem<Save>(env);
|
||||
items["exit"] = CreateItem<Exit>(env);
|
||||
items["panic"] = CreateItem<Panic>(env);
|
||||
return items;
|
||||
}
|
||||
template <typename T>
|
||||
static std::unique_ptr<nf7::File> CreateItem(nf7::Env& env) noexcept {
|
||||
static nf7::GenericTypeInfo<NodeFile<T>> kType = {T::kTypeName, {}};
|
||||
return std::make_unique<NodeFile<T>>(kType, env);
|
||||
}
|
||||
};
|
||||
|
||||
void SysNode::UpdateTree() noexcept {
|
||||
for (const auto& p : dir_.items()) {
|
||||
auto& f = *p.second;
|
||||
|
||||
constexpr auto kFlags =
|
||||
ImGuiTreeNodeFlags_Leaf |
|
||||
ImGuiTreeNodeFlags_NoTreePushOnOpen |
|
||||
ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
ImGui::TreeNodeEx(p.first.c_str(), kFlags);
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
p.second->type().UpdateTooltip();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
if (ImGui::BeginDragDropSource()) {
|
||||
gui::dnd::Send(gui::dnd::kFilePath, f.abspath());
|
||||
ImGui::TextDisabled(f.abspath().Stringify().c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
class SysNode::NodeFile final : public nf7::File, public nf7::Node {
|
||||
public:
|
||||
static inline const char* kTypeDescription = T::kTypeDescription;
|
||||
|
||||
NodeFile(const nf7::File::TypeInfo& t, nf7::Env& env) noexcept :
|
||||
nf7::File(t, env),
|
||||
nf7::Node(nf7::Node::kNone) {
|
||||
}
|
||||
|
||||
void Serialize(nf7::Serializer&) const noexcept override {}
|
||||
std::unique_ptr<nf7::File> Clone(nf7::Env& env) const noexcept override {
|
||||
return std::make_unique<NodeFile<T>>(type(), env);
|
||||
}
|
||||
|
||||
std::shared_ptr<nf7::Node::Lambda> CreateLambda(
|
||||
const std::shared_ptr<nf7::Node::Lambda>& parent) noexcept override {
|
||||
return std::make_shared<T>(*this, parent);
|
||||
}
|
||||
nf7::Node::Meta GetMeta() const noexcept override {
|
||||
return T::kMeta;
|
||||
}
|
||||
|
||||
nf7::File::Interface* interface(const std::type_info& t) noexcept override {
|
||||
return nf7::InterfaceSelector<nf7::Node>(t).Select(this);
|
||||
}
|
||||
};
|
||||
|
||||
class SysNode::Save final : public nf7::Node::Lambda,
|
||||
public std::enable_shared_from_this<Save> {
|
||||
public:
|
||||
using nf7::Node::Lambda::Lambda;
|
||||
|
||||
static inline const char* kTypeName = "System/Node/Save";
|
||||
static inline const char* kTypeDescription = "Persists the filesystem root";
|
||||
|
||||
static inline const nf7::Node::Meta kMeta = { {"exec"}, {}, };
|
||||
|
||||
void Handle(const nf7::Node::Lambda::Msg&) noexcept override {
|
||||
env().ExecMain(shared_from_this(), [this]() {
|
||||
env().Save();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class SysNode::Exit final : public nf7::Node::Lambda {
|
||||
public:
|
||||
using nf7::Node::Lambda::Lambda;
|
||||
|
||||
static inline const char* kTypeName = "System/Node/Exit";
|
||||
static inline const char* kTypeDescription = "Terminates Nf7 immediately";
|
||||
|
||||
static inline const nf7::Node::Meta kMeta = { {"exec"}, {}, };
|
||||
|
||||
void Handle(const nf7::Node::Lambda::Msg&) noexcept override {
|
||||
env().Exit();
|
||||
}
|
||||
};
|
||||
|
||||
class SysNode::Panic final : public nf7::Node::Lambda {
|
||||
public:
|
||||
using nf7::Node::Lambda::Lambda;
|
||||
|
||||
static inline const char* kTypeName = "System/Node/Panic";
|
||||
static inline const char* kTypeDescription = "Causes a panic";
|
||||
|
||||
static inline const nf7::Node::Meta kMeta = { {"exec"}, {}, };
|
||||
|
||||
void Handle(const nf7::Node::Lambda::Msg& in) noexcept override {
|
||||
try {
|
||||
if (in.value.isString()) {
|
||||
throw nf7::Exception {in.value.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/Node"}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace nf7
|
23
init.hh
23
init.hh
@ -7,14 +7,23 @@
|
||||
|
||||
inline std::unique_ptr<nf7::File> CreateRoot(nf7::Env& env) noexcept {
|
||||
auto ret = nf7::File::registry("System/Dir").Create(env);
|
||||
auto& dir = ret->interfaceOrThrow<nf7::Dir>();
|
||||
auto& root = ret->interfaceOrThrow<nf7::Dir>();
|
||||
|
||||
dir.Add("_audio", nf7::File::registry("Audio/Context").Create(env));
|
||||
dir.Add("_font", nf7::File::registry("Font/Context").Create(env));
|
||||
dir.Add("_imgui", nf7::File::registry("System/ImGui").Create(env));
|
||||
dir.Add("_logger", nf7::File::registry("System/Logger").Create(env));
|
||||
dir.Add("_luajit", nf7::File::registry("LuaJIT/Context").Create(env));
|
||||
const auto Add = [&](nf7::Dir& dir, const char* name, const char* type) -> nf7::File& {
|
||||
return dir.Add(name, nf7::File::registry(type).Create(env));
|
||||
};
|
||||
|
||||
dir.Add("home", nf7::File::registry("System/Dir").Create(env));
|
||||
Add(root, "_audio", "Audio/Context");
|
||||
Add(root, "_font", "Font/Context");
|
||||
Add(root, "_imgui", "System/ImGui");
|
||||
Add(root, "_logger", "System/Logger");
|
||||
Add(root, "_luajit", "LuaJIT/Context");
|
||||
|
||||
auto& node = Add(root, "node", "System/Dir").interfaceOrThrow<nf7::Dir>();
|
||||
{
|
||||
Add(node, "system", "System/Node");
|
||||
}
|
||||
|
||||
Add(root, "home", "System/Dir").interfaceOrThrow<nf7::Dir>();
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user