SatDump 2.0.0-alpha-76a915210
Loading...
Searching...
No Matches
flowgraph.h
1#pragma once
2
3#include "nlohmann/json.hpp"
4#include <string>
5#include <vector>
6
8#include "core/style.h"
9#include "imgui/imgui.h"
10#include "imgui/imgui_stdlib.h"
11#include "logger.h"
12
13#include "dsp/block.h"
14
15#include "common/widgets/json_editor.h"
16
17// #include "variable_manager.h"
18
19#include "node_int.h"
20
21namespace satdump
22{
23 namespace ndsp
24 {
25 class Flowgraph
26 {
27 public:
29 {
30 std::string menuname;
31 std::function<std::shared_ptr<NodeInternal>(const Flowgraph *f)> func;
32 };
33 std::map<std::string, NodeInternalReg> node_internal_registry;
34
35 public:
36 class Node
37 {
38 friend class Flowgraph;
39
40 private:
41 Flowgraph *_f;
42
43 const int id;
44 const std::string title;
45 const std::string internal_id;
46 const std::shared_ptr<NodeInternal> internal;
47
48 bool pos_was_set = false;
49 float pos_x = 0;
50 float pos_y = 0;
51
52 struct InOut
53 {
54 int id;
55 std::string name;
56 bool is_out;
57
58 NLOHMANN_DEFINE_TYPE_INTRUSIVE(InOut, id, name, is_out);
59 };
60
61 std::vector<InOut> node_io;
62
63 void updateIO()
64 {
65 node_io.clear();
66 for (auto &io : internal->blk->get_inputs())
67 node_io.push_back({_f->getNewNodeIOID(&node_io), io.name, false});
68 for (auto &io : internal->blk->get_outputs())
69 node_io.push_back({_f->getNewNodeIOID(&node_io), io.name, true});
70 }
71
72 public:
73 Node(Flowgraph *f, std::string id, std::shared_ptr<NodeInternal> i) : _f(f), id(f->getNewNodeID()), internal_id(id), title(i->blk->d_id), internal(i) { updateIO(); }
74
75 Node(Flowgraph *f, nlohmann::json j, std::shared_ptr<NodeInternal> i)
76 : id(j["id"]), internal_id(j["int_id"]), title(i->blk->d_id), node_io(j["io"].get<std::vector<InOut>>()), internal(i)
77 {
78 if (j.contains("int_cfg"))
79 internal->setP(j["int_cfg"]);
80
81 pos_x = j.contains("pos_x") ? j["pos_x"].get<float>() : 0;
82 pos_y = j.contains("pos_y") ? j["pos_y"].get<float>() : 0;
83 }
84
85 nlohmann::json getJSON()
86 {
87 nlohmann::json j;
88 j["id"] = id;
89 j["io"] = node_io;
90 j["int_id"] = internal_id;
91 j["int_cfg"] = internal->getP();
92 j["pos_x"] = pos_x;
93 j["pos_y"] = pos_y;
94 return j;
95 }
96 };
97
98 struct Link
99 {
100 int id;
101 int start;
102 int end;
103
104 NLOHMANN_DEFINE_TYPE_INTRUSIVE(Link, id, start, end);
105 };
106
107 private:
108 std::vector<std::shared_ptr<Node>> nodes;
109 std::vector<Link> links;
110
111 int getNewNodeID();
112 int getNewNodeIOID(std::vector<Node::InOut> *ptr = nullptr);
113 int getNewLinkID();
114
115 void renderAddMenu(std::pair<const std::string, NodeInternalReg> &opt, std::vector<std::string> cats, int pos);
116
117 public:
118 Flowgraph();
119 ~Flowgraph();
120
121 // LuaVariableManager var_manager_test;
122
123 std::shared_ptr<Node> addNode(std::string id, std::shared_ptr<NodeInternal> i)
124 {
125 auto ptr = std::make_shared<Node>(this, id, i);
126 nodes.push_back(ptr);
127 return ptr;
128 }
129
130 void render();
131
132 nlohmann::json getJSON()
133 {
134 nlohmann::json j;
135 for (auto &n : nodes)
136 j["nodes"][n->id] = n->getJSON();
137 j["links"] = links;
138 // j["vars"] = var_manager_test.variables;
139 return j;
140 }
141
142 void setJSON(nlohmann::json j)
143 {
144 // var_manager_test.variables = j["vars"];
145
146 nodes.clear();
147 links.clear();
148
149 for (auto &n : j["nodes"].items())
150 {
151 if (node_internal_registry.count(n.value()["int_id"]))
152 {
153 auto i = node_internal_registry[n.value()["int_id"]].func(this);
154 nodes.push_back(std::make_shared<Node>(this, n.value(), i));
155 }
156 else
157 {
158 logger->error("Could not find node with ID : " + n.value()["int_id"].get<std::string>());
159 }
160 }
161
162 // Links need to be filtered in case some blocks are missing!
163 std::vector<Link> tmp_links = j["links"];
164
165 for (auto &link : tmp_links)
166 {
167 bool got_in = false, got_ou = false;
168 for (auto &n : nodes)
169 {
170 for (auto &io : n->node_io)
171 {
172 if (io.id == link.start)
173 got_in = true;
174 if (io.id == link.end)
175 got_ou = true;
176 }
177 }
178
179 if (got_in && got_ou)
180 links.push_back(link);
181 }
182 }
183
184 public:
185 bool is_running = false;
186
187 void run();
188 void stop();
189 };
190 } // namespace ndsp
191} // namespace satdump