Commit 232e49e3 authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

core: add grah i/o

parent a62376e9
Pipeline #10984 failed with stage
in 57 seconds
...@@ -56,16 +56,15 @@ Simple file ...@@ -56,16 +56,15 @@ Simple file
[source] [source]
'''' ''''
# '#' means comment until end of line
4 # 4 models will be allocated 4 # 4 models will be allocated
A generator 2 0.0 100.0 0 # Model 'A' is a generator with one double real message 0 A generator 2 0.0 100.0 0 # Model 'A' is a generator with one double real message
B generator 2 0.0 100.0 0 # Model 'B' is a generator with one double real message 1 B generator 2 0.0 100.0 0 # Model 'B' is a generator with one double real message
Add adder_2 2 1.0 1.0 0 # Model 'Add' is a adder_2 with one double real message 2 Add adder_2 2 1.0 1.0 0 # Model 'Add' is a adder_2 with one double real message
C counter 1 0.0 0 # Model 'C' is a counter with one real message 3 C counter 1 0.0 0 # Model 'C' is a counter with one real message
3 # 3 internal connections 3 # 3 internal connections
A 0 Add 0 # Model 'A' output port '0' connected to model 'Add' input port '0' 0 0 2 0 # Model 'A' output port '0' connected to model 'Add' input port '0'
B 0 Add 1 # Model 'A' output port '0' connected to model 'Add' input port '0' 1 0 2 1 # Model 'A' output port '0' connected to model 'Add' input port '0'
Add 0 C 0 # Model 'Add' output port '0' connected to model 'C' input port '0' 2 0 3 0 # Model 'Add' output port '0' connected to model 'C' input port '0'
0 # 0 input connection 0 # 0 input connection
1 # 1 output connection 1 # 1 output connection
C 0 0 # Model 'C' output port '0' connected to coupled model port '0' C 0 0 # Model 'C' output port '0' connected to coupled model port '0'
......
...@@ -1111,9 +1111,10 @@ show_editor(const char* editor_name, editor& ed) ...@@ -1111,9 +1111,10 @@ show_editor(const char* editor_name, editor& ed)
} }
{ {
const int num_selected = imnodes::NumSelectedLinks();
if (num_selected > 0 && ImGui::IsKeyReleased('D')) {
static array<int> selected_links; static array<int> selected_links;
const int num_selected = imnodes::NumSelectedLinks();
if (num_selected > 0 && ImGui::IsKeyReleased('X')) {
if (selected_links.capacity() < static_cast<size_t>(num_selected)) if (selected_links.capacity() < static_cast<size_t>(num_selected))
selected_links.init(num_selected); selected_links.init(num_selected);
...@@ -1131,10 +1132,13 @@ show_editor(const char* editor_name, editor& ed) ...@@ -1131,10 +1132,13 @@ show_editor(const char* editor_name, editor& ed)
} }
{ {
const int num_selected = imnodes::NumSelectedNodes();
if (num_selected > 0 && ImGui::IsKeyReleased('D')) {
static array<int> selected_nodes; static array<int> selected_nodes;
if (selected_nodes.capacity() < static_cast<size_t>(num_selected))
const int num_selected = imnodes::NumSelectedNodes();
if (num_selected > 0) {
if (ImGui::IsKeyReleased('X')) {
if (selected_nodes.capacity() <
static_cast<size_t>(num_selected))
selected_nodes.init(num_selected); selected_nodes.init(num_selected);
std::fill_n(selected_nodes.data(), selected_nodes.size(), -1); std::fill_n(selected_nodes.data(), selected_nodes.size(), -1);
...@@ -1144,6 +1148,14 @@ show_editor(const char* editor_name, editor& ed) ...@@ -1144,6 +1148,14 @@ show_editor(const char* editor_name, editor& ed)
ed.free(node_id); ed.free(node_id);
selected_nodes.clear(); selected_nodes.clear();
} else if (ImGui::IsKeyReleased('D')) {
if (selected_nodes.capacity() <
static_cast<size_t>(num_selected))
selected_nodes.init(num_selected);
std::fill_n(selected_nodes.data(), selected_nodes.size(), -1);
imnodes::GetSelectedNodes(selected_nodes.data());
}
} }
} }
......
...@@ -117,7 +117,15 @@ enum class status ...@@ -117,7 +117,15 @@ enum class status
gui_not_enough_memory, gui_not_enough_memory,
gui_too_many_model, gui_too_many_model,
gui_too_many_connection gui_too_many_connection,
io_file_format_error,
io_file_format_model_error,
io_file_format_model_number_error,
io_file_format_model_unknown,
io_file_format_dynamics_unknown,
io_file_format_dynamics_limit_reach,
io_file_format_dynamics_init_error
}; };
constexpr bool constexpr bool
...@@ -4157,7 +4165,6 @@ struct simulation ...@@ -4157,7 +4165,6 @@ struct simulation
time begin = time_domain<time>::zero; time begin = time_domain<time>::zero;
time end = time_domain<time>::infinity; time end = time_domain<time>::infinity;
private:
template<typename Function> template<typename Function>
status dispatch(const dynamics_type type, Function f) noexcept status dispatch(const dynamics_type type, Function f) noexcept
{ {
...@@ -4195,35 +4202,72 @@ private: ...@@ -4195,35 +4202,72 @@ private:
irt_bad_return(status::unknown_dynamics); irt_bad_return(status::unknown_dynamics);
} }
template<typename Dynamics> template<typename Function>
int get_input_port_index(const Dynamics& dynamics, status dispatch(const dynamics_type type, Function f) const noexcept
const input_port_id id) const noexcept
{ {
static_assert(is_detected_v<has_input_port_t, Dynamics>); switch (type) {
case dynamics_type::none:
auto it = std::find(std::begin(dynamics.x), std::end(dynamics.x), id); return f(none_models);
if (it == std::end(dynamics.x)) case dynamics_type::integrator:
return -1; return f(integrator_models);
case dynamics_type::quantifier:
return f(quantifier_models);
case dynamics_type::adder_2:
return f(adder_2_models);
case dynamics_type::adder_3:
return f(adder_3_models);
case dynamics_type::adder_4:
return f(adder_4_models);
case dynamics_type::mult_2:
return f(mult_2_models);
case dynamics_type::mult_3:
return f(mult_3_models);
case dynamics_type::mult_4:
return f(mult_4_models);
case dynamics_type::counter:
return f(counter_models);
case dynamics_type::generator:
return f(generator_models);
case dynamics_type::constant:
return f(constant_models);
case dynamics_type::cross:
return f(cross_models);
case dynamics_type::time_func:
return f(time_func_models);
}
return static_cast<int>(std::distance(std::begin(dynamics.x), it)); irt_bad_return(status::unknown_dynamics);
} }
template<typename Dynamics> //template<typename Dynamics>
int get_output_port_index(const Dynamics& dynamics, //int get_input_port_index(const Dynamics& dynamics,
const output_port_id id) const noexcept // const input_port_id id) const noexcept
{ //{
static_assert(is_detected_v<has_output_port_t, Dynamics>); // static_assert(is_detected_v<has_input_port_t, Dynamics>);
auto it = std::find(std::begin(dynamics.y), std::end(dynamics.y), id); // auto it = std::find(std::begin(dynamics.x), std::end(dynamics.x), id);
if (it == std::end(dynamics.y)) // if (it == std::end(dynamics.x))
return -1; // return -1;
return static_cast<int>(std::distance(std::begin(dynamics.y), it)); // return static_cast<int>(std::distance(std::begin(dynamics.x), it));
} //}
//template<typename Dynamics>
//int get_output_port_index(const Dynamics& dynamics,
// const output_port_id id) const noexcept
//{
// static_assert(is_detected_v<has_output_port_t, Dynamics>);
// auto it = std::find(std::begin(dynamics.y), std::end(dynamics.y), id);
// if (it == std::end(dynamics.y))
// return -1;
// return static_cast<int>(std::distance(std::begin(dynamics.y), it));
//}
status get_output_port_index(const model& mdl, status get_output_port_index(const model& mdl,
const output_port_id port, const output_port_id port,
int* index) noexcept int* index) const noexcept
{ {
return dispatch( return dispatch(
mdl.type, mdl.type,
...@@ -4250,7 +4294,7 @@ private: ...@@ -4250,7 +4294,7 @@ private:
status get_input_port_index(const model& mdl, status get_input_port_index(const model& mdl,
const input_port_id port, const input_port_id port,
int* index) noexcept int* index) const noexcept
{ {
return dispatch( return dispatch(
mdl.type, mdl.type,
...@@ -4277,7 +4321,7 @@ private: ...@@ -4277,7 +4321,7 @@ private:
status get_output_port_id(const model& mdl, status get_output_port_id(const model& mdl,
int index, int index,
output_port_id* port) noexcept output_port_id* port) const noexcept
{ {
return dispatch( return dispatch(
mdl.type, mdl.type,
...@@ -4305,7 +4349,7 @@ private: ...@@ -4305,7 +4349,7 @@ private:
status get_input_port_id(const model& mdl, status get_input_port_id(const model& mdl,
int index, int index,
input_port_id* port) noexcept input_port_id* port) const noexcept
{ {
return dispatch( return dispatch(
mdl.type, mdl.type,
......
This diff is collapsed.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <irritator/core.hpp> #include <irritator/core.hpp>
#include <irritator/io.hpp>
#include <boost/ut.hpp> #include <boost/ut.hpp>
...@@ -10,84 +11,6 @@ ...@@ -10,84 +11,6 @@
#include <cstdio> #include <cstdio>
static void
dot_graph_save(const irt::simulation& sim, std::FILE* os)
{
/* With input and output port.
digraph graphname{
graph[rankdir = "LR"];
node[shape = "record"];
edge[];
"sum_a"[label = "sum-a | <f0> | <f1>"];
"sum_a":f0->int_a[id = 1];
sum_b->int_b[label = "2-10"];
prod->sum_b[label = "3-4"];
prod -> "sum_a":f0[label = "3-2"];
int_a->qua_a[label = "4-11"];
int_a->prod[label = "4-5"];
int_a -> "sum_a":f1[label = "4-1"];
int_b->qua_b[label = "5-12"];
int_b->prod[label = "5-6"];
int_b->sum_b[label = "5-3"];
qua_a->int_a[label = "6-7"];
qua_b->int_b[label = "7-9"];
}
*/
!boost::ut::expect(os != nullptr);
std::fputs("digraph graphname {\n", os);
irt::output_port* output_port = nullptr;
while (sim.output_ports.next(output_port)) {
for (const irt::input_port_id dst : output_port->connections) {
if (auto* input_port = sim.input_ports.try_to_get(dst);
input_port) {
auto* mdl_src = sim.models.try_to_get(output_port->model);
auto* mdl_dst = sim.models.try_to_get(input_port->model);
if (!(mdl_src && mdl_dst))
continue;
if (mdl_src->name.empty())
fmt::print(os, "{} -> ", irt::get_key(output_port->model));
else
fmt::print(os, "{} -> ", mdl_src->name.c_str());
if (mdl_dst->name.empty())
fmt::print(os, "{}", irt::get_key(input_port->model));
else
fmt::print(os, "{}", mdl_dst->name.c_str());
std::fputs(" [label=\"", os);
if (output_port->name.empty())
fmt::print(
os,
"{}",
irt::get_key(sim.output_ports.get_id(*output_port)));
else
fmt::print(os, "{}", output_port->name.c_str());
std::fputs("-", os);
if (input_port->name.empty())
fmt::print(
os,
"{}",
irt::get_key(sim.input_ports.get_id(*input_port)));
else
fmt::print(os, "{}", input_port->name.c_str());
std::fputs("\"];\n", os);
}
}
}
}
double double
f(double t) noexcept f(double t) noexcept
{ {
...@@ -1098,7 +1021,7 @@ main() ...@@ -1098,7 +1021,7 @@ main()
expect(sim.connect(integrator_b.y[0], quantifier_b.x[0]) == expect(sim.connect(integrator_b.y[0], quantifier_b.x[0]) ==
irt::status::success); irt::status::success);
dot_graph_save(sim, stdout); irt::dot_writer(stdout)(sim);
file_output fo_a("lotka-volterra_a.csv"); file_output fo_a("lotka-volterra_a.csv");
file_output fo_b("lotka-volterra_b.csv"); file_output fo_b("lotka-volterra_b.csv");
...@@ -1279,7 +1202,7 @@ main() ...@@ -1279,7 +1202,7 @@ main()
irt::status::success); irt::status::success);
expect(sim.connect(constant.y[0], sum_d.x[1]) == irt::status::success); expect(sim.connect(constant.y[0], sum_d.x[1]) == irt::status::success);
dot_graph_save(sim, stdout); irt::dot_writer(stdout)(sim);
file_output fo_a("izhikevitch_a.csv"); file_output fo_a("izhikevitch_a.csv");
file_output fo_b("izhikevitch_b.csv"); file_output fo_b("izhikevitch_b.csv");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment