Commit a8c2f4fa authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

gui: add menu to clear and add predefined models

parent 8e4c77b8
Pipeline #10416 failed with stage
in 1 minute and 2 seconds
...@@ -62,6 +62,8 @@ run_simulation(simulation& sim, ...@@ -62,6 +62,8 @@ run_simulation(simulation& sim,
} }
} while (current < end && !stop); } while (current < end && !stop);
sim.clean();
st = simulation_status::success; st = simulation_status::success;
} }
...@@ -108,6 +110,16 @@ struct editor ...@@ -108,6 +110,16 @@ struct editor
int current_connection_id = 0; int current_connection_id = 0;
bool initialized = false; bool initialized = false;
void clear()
{
g_input_ports.clear();
g_output_ports.clear();
g_models.clear();
g_connections.clear();
sim.clear();
}
model_id get_model(int index) const noexcept model_id get_model(int index) const noexcept
{ {
for (size_t i = 0, e = g_models.size(); i != e; ++i) for (size_t i = 0, e = g_models.size(); i != e; ++i)
...@@ -417,6 +429,122 @@ struct editor ...@@ -417,6 +429,122 @@ struct editor
return status::success; return status::success;
} }
status initialize_izhikevitch()
{
auto& constant = sim.constant_models.alloc();
auto& constant2 = sim.constant_models.alloc();
auto& constant3 = sim.constant_models.alloc();
auto& sum_a = sim.adder_2_models.alloc();
auto& sum_b = sim.adder_2_models.alloc();
auto& sum_c = sim.adder_4_models.alloc();
auto& sum_d = sim.adder_2_models.alloc();
auto& product = sim.mult_2_models.alloc();
auto& integrator_a = sim.integrator_models.alloc();
auto& integrator_b = sim.integrator_models.alloc();
auto& quantifier_a = sim.quantifier_models.alloc();
auto& quantifier_b = sim.quantifier_models.alloc();
auto& cross = sim.cross_models.alloc();
auto& cross2 = sim.cross_models.alloc();
double a = 0.2;
double b = 2.0;
double c = -56.0;
double d = -16.0;
double I = -99.0;
double vt = 30.0;
constant.default_value = 1.0;
constant2.default_value = c;
constant3.default_value = I;
cross.default_threshold = vt;
cross2.default_threshold = vt;
integrator_a.default_current_value = 0.0;
quantifier_a.default_adapt_state =
irt::quantifier::adapt_state::possible;
quantifier_a.default_zero_init_offset = true;
quantifier_a.default_step_size = 0.01;
quantifier_a.default_past_length = 3;
integrator_b.default_current_value = 0.0;
quantifier_b.default_adapt_state =
irt::quantifier::adapt_state::possible;
quantifier_b.default_zero_init_offset = true;
quantifier_b.default_step_size = 0.01;
quantifier_b.default_past_length = 3;
product.default_input_coeffs[0] = 1.0;
product.default_input_coeffs[1] = 1.0;
sum_a.default_input_coeffs[0] = 1.0;
sum_a.default_input_coeffs[1] = -1.0;
sum_b.default_input_coeffs[0] = -a;
sum_b.default_input_coeffs[1] = a * b;
sum_c.default_input_coeffs[0] = 0.04;
sum_c.default_input_coeffs[1] = 5.0;
sum_c.default_input_coeffs[2] = 140.0;
sum_c.default_input_coeffs[3] = 1.0;
sum_d.default_input_coeffs[0] = 1.0;
sum_d.default_input_coeffs[1] = d;
irt_return_if_fail(sim.models.can_alloc(14), status::gui_too_many_model);
irt_return_if_bad(alloc(constant3, sim.constant_models.get_id(constant3), "tfun"));
irt_return_if_bad(alloc(constant, sim.constant_models.get_id(constant), "1.0"));
irt_return_if_bad(alloc(constant2, sim.constant_models.get_id(constant2), "-56.0"));
irt_return_if_bad(alloc(sum_a, sim.adder_2_models.get_id(sum_a), "sum_a"));
irt_return_if_bad(alloc(sum_b, sim.adder_2_models.get_id(sum_b), "sum_b"));
irt_return_if_bad(alloc(sum_c, sim.adder_4_models.get_id(sum_c), "sum_c"));
irt_return_if_bad(alloc(sum_d, sim.adder_2_models.get_id(sum_d), "sum_d"));
irt_return_if_bad(alloc(product, sim.mult_2_models.get_id(product), "prod"));
irt_return_if_bad(alloc(integrator_a, sim.integrator_models.get_id(integrator_a), "int_a"));
irt_return_if_bad(alloc(integrator_b, sim.integrator_models.get_id(integrator_b), "int_b"));
irt_return_if_bad(alloc(quantifier_a, sim.quantifier_models.get_id(quantifier_a), "qua_a"));
irt_return_if_bad(alloc(quantifier_b, sim.quantifier_models.get_id(quantifier_b), "qua_b"));
irt_return_if_bad(alloc(cross, sim.cross_models.get_id(cross), "cross"));
irt_return_if_bad(alloc(cross2, sim.cross_models.get_id(cross2), "cross2"));
irt_return_if_bad(connect(integrator_a.y[0], cross.x[0]));
irt_return_if_bad(connect(constant2.y[0], cross.x[1]));
irt_return_if_bad(connect(integrator_a.y[0], cross.x[2]));
irt_return_if_bad(connect(cross.y[0], quantifier_a.x[0]));
irt_return_if_bad(connect(cross.y[0], product.x[0]));
irt_return_if_bad(connect(cross.y[0], product.x[1]));
irt_return_if_bad(connect(product.y[0], sum_c.x[0]));
irt_return_if_bad(connect(cross.y[0], sum_c.x[1]));
irt_return_if_bad(connect(cross.y[0], sum_b.x[1]));
irt_return_if_bad(connect(constant.y[0], sum_c.x[2]));
irt_return_if_bad(connect(constant3.y[0], sum_c.x[3]));
irt_return_if_bad(connect(sum_c.y[0], sum_a.x[0]));
irt_return_if_bad(connect(integrator_b.y[0], sum_a.x[1]));
irt_return_if_bad(connect(cross2.y[0], sum_a.x[1]));
irt_return_if_bad(connect(sum_a.y[0], integrator_a.x[1]));
irt_return_if_bad(connect(cross.y[0], integrator_a.x[2]));
irt_return_if_bad(connect(quantifier_a.y[0], integrator_a.x[0]));
irt_return_if_bad(connect(cross2.y[0], quantifier_b.x[0]));
irt_return_if_bad(connect(cross2.y[0], sum_b.x[0]));
irt_return_if_bad(connect(quantifier_b.y[0], integrator_b.x[0]));
irt_return_if_bad(connect(sum_b.y[0], integrator_b.x[1]));
irt_return_if_bad(connect(cross2.y[0], integrator_b.x[2]));
irt_return_if_bad(connect(integrator_a.y[0], cross2.x[0]));
irt_return_if_bad(connect(integrator_b.y[0], cross2.x[2]));
irt_return_if_bad(connect(sum_d.y[0], cross2.x[1]));
irt_return_if_bad(connect(integrator_b.y[0], sum_d.x[0]));
irt_return_if_bad(connect(constant.y[0], sum_d.x[1]));
return status::success;
}
}; };
static void static void
...@@ -684,23 +812,40 @@ show_editor(const char* editor_name, editor& ed) ...@@ -684,23 +812,40 @@ show_editor(const char* editor_name, editor& ed)
{ {
imnodes::EditorContextSet(ed.context); imnodes::EditorContextSet(ed.context);
ImGui::Begin(editor_name); ImGuiWindowFlags windows_flags = 0;
ImGui::TextUnformatted("D -- delete selected nodes and/or connections"); windows_flags |= ImGuiWindowFlags_MenuBar;
imnodes::BeginNodeEditor(); ImGui::Begin(editor_name, nullptr, windows_flags);
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("Edition")) {
if (ImGui::MenuItem("Clear"))
ed.clear();
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Examples")) {
if (ImGui::MenuItem("Insert Lotka Volterra model")) {
if (is_bad(ed.initialize_lotka_volterra()))
fmt::print("Error: fail to initialize a lotka volterra");
}
if (ImGui::MenuItem("Insert Izzhikevitch model")) {
if (is_bad(ed.initialize_izhikevitch()))
fmt::print(stderr, "fail to initialize an Izzhikevitch model\n");
}
//irt::model* mdl = nullptr; ImGui::EndMenu();
//while (ed.sim.models.next(mdl)) { }
// imnodes::BeginNode(ed.get_model(ed.sim.models.get_id(mdl)));
// imnodes::BeginNodeTitleBar(); ImGui::EndMenuBar();
// ImGui::TextUnformatted(mdl->name.c_str()); }
// imnodes::EndNodeTitleBar();
// show_model_dynamics(ed, *mdl); ImGui::Text("D -- delete selected nodes and/or connections");
imnodes::BeginNodeEditor();
// imnodes::EndNode();
//}
for (size_t i = 0, e = ed.g_models.size(); i != e; ++i) { for (size_t i = 0, e = ed.g_models.size(); i != e; ++i) {
irt::model* mdl = ed.sim.models.try_to_get(ed.g_models[i].id); irt::model* mdl = ed.sim.models.try_to_get(ed.g_models[i].id);
...@@ -718,6 +863,7 @@ show_editor(const char* editor_name, editor& ed) ...@@ -718,6 +863,7 @@ show_editor(const char* editor_name, editor& ed)
} }
show_connections(ed); show_connections(ed);
imnodes::EndNodeEditor();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
...@@ -835,7 +981,6 @@ show_editor(const char* editor_name, editor& ed) ...@@ -835,7 +981,6 @@ show_editor(const char* editor_name, editor& ed)
ImGui::PopStyleVar(); ImGui::PopStyleVar();
imnodes::EndNodeEditor();
{ {
int start = 0, end = 0; int start = 0, end = 0;
...@@ -995,7 +1140,6 @@ node_editor_initialize() ...@@ -995,7 +1140,6 @@ node_editor_initialize()
return; return;
} }
ed.initialize_lotka_volterra();
ed.context = imnodes::EditorContextCreate(); ed.context = imnodes::EditorContextCreate();
} }
......
...@@ -112,6 +112,7 @@ enum class status ...@@ -112,6 +112,7 @@ enum class status
model_time_func_bad_init_message, model_time_func_bad_init_message,
gui_not_enough_memory, gui_not_enough_memory,
gui_too_many_model,
gui_too_many_connection gui_too_many_connection
}; };
...@@ -2108,7 +2109,6 @@ public: ...@@ -2108,7 +2109,6 @@ public:
m_max_size = 0; m_max_size = 0;
m_max_used = 0; m_max_used = 0;
m_capacity = 0;
m_next_key = 1; m_next_key = 1;
m_free_head = none; m_free_head = none;
} }
...@@ -2424,6 +2424,11 @@ public: ...@@ -2424,6 +2424,11 @@ public:
return status::success; return status::success;
} }
void clear() noexcept
{
data.clear();
}
template<typename... Args> template<typename... Args>
T& alloc(Args&&... args) noexcept T& alloc(Args&&... args) noexcept
{ {
...@@ -2606,12 +2611,22 @@ public: ...@@ -2606,12 +2611,22 @@ public:
return; return;
} }
assert(m_size > 0); if (m_size > 0) {
m_size--;
detach_subheap(elem);
elem = merge_subheaps(elem);
root = merge(root, elem);
}
else {
root = nullptr;
}
m_size--; //assert(m_size > 0);
detach_subheap(elem);
elem = merge_subheaps(elem); //m_size--;
root = merge(root, elem); //detach_subheap(elem);
//elem = merge_subheaps(elem);
//root = merge(root, elem);
} }
void pop() noexcept void pop() noexcept
...@@ -4019,6 +4034,65 @@ struct simulation ...@@ -4019,6 +4034,65 @@ struct simulation
return models.can_alloc(place); return models.can_alloc(place);
} }
/**
* @brief cleanup simulation object
*
* Clean scheduller and input/output port from message. This function
* must be call at the end of the simulation.
*/
void clean() noexcept
{
sched.clear();
output_port* out = nullptr;
while (output_ports.next(out))
out->messages.clear();
input_port* in = nullptr;
while (input_ports.next(in))
in->messages.clear();
}
/**
* @brief cleanup simulation and destroy all models and connections
*/
void clear() noexcept
{
clean();
model_list_allocator.reset();
message_list_allocator.reset();
input_port_list_allocator.reset();
output_port_list_allocator.reset();
emitting_output_port_allocator.reset();
models.clear();
init_messages.clear();
messages.clear();
input_ports.clear();
output_ports.clear();
none_models.clear();
integrator_models.clear();
quantifier_models.clear();
adder_2_models.clear();
adder_3_models.clear();
adder_4_models.clear();
mult_2_models.clear();
mult_3_models.clear();
mult_4_models.clear();
counter_models.clear();
generator_models.clear();
constant_models.clear();
cross_models.clear();
time_func_models.clear();
begin = time_domain<time>::zero;
end = time_domain<time>::infinity;
}
template<typename Dynamics> template<typename Dynamics>
status alloc(Dynamics& dynamics, status alloc(Dynamics& dynamics,
dynamics_id id, dynamics_id id,
...@@ -4267,15 +4341,7 @@ struct simulation ...@@ -4267,15 +4341,7 @@ struct simulation
status initialize(time t) noexcept status initialize(time t) noexcept
{ {
sched.clear(); clean();
input_port* in = nullptr;
while (input_ports.next(in))
in->messages.clear();
output_port* out = nullptr;
while (output_ports.next(out))
out->messages.clear();
irt::model* mdl = nullptr; irt::model* mdl = nullptr;
while (models.next(mdl)) while (models.next(mdl))
......
...@@ -514,7 +514,7 @@ main() ...@@ -514,7 +514,7 @@ main()
expect(array.max_size() == 0); expect(array.max_size() == 0);
expect(array.max_used() == 0); expect(array.max_used() == 0);
expect(array.capacity() == 0); expect(array.capacity() == 3);
expect(array.next_key() == 1); expect(array.next_key() == 1);
expect(array.is_free_list_empty()); expect(array.is_free_list_empty());
...@@ -922,7 +922,6 @@ main() ...@@ -922,7 +922,6 @@ main()
quantifier_b, sim.quantifier_models.get_id(quantifier_b), "qua_b"))); quantifier_b, sim.quantifier_models.get_id(quantifier_b), "qua_b")));
!expect(sim.models.size() == 7_ul); !expect(sim.models.size() == 7_ul);
!expect(sim.sched.size() == 7_ul);
expect(sim.connect(sum_a.y[0], integrator_a.x[1]) == expect(sim.connect(sum_a.y[0], integrator_a.x[1]) ==
irt::status::success); irt::status::success);
...@@ -956,6 +955,7 @@ main() ...@@ -956,6 +955,7 @@ main()
irt::time t = 0.0; irt::time t = 0.0;
expect(sim.initialize(t) == irt::status::success); expect(sim.initialize(t) == irt::status::success);
!expect(sim.sched.size() == 7_ul);
std::FILE* os = std::fopen("output.csv", "w"); std::FILE* os = std::fopen("output.csv", "w");
!expect(os != nullptr); !expect(os != nullptr);
...@@ -1081,7 +1081,6 @@ main() ...@@ -1081,7 +1081,6 @@ main()
sim.alloc(cross2, sim.cross_models.get_id(cross2), "cross2"))); sim.alloc(cross2, sim.cross_models.get_id(cross2), "cross2")));
!expect(sim.models.size() == 14_ul); !expect(sim.models.size() == 14_ul);
!expect(sim.sched.size() == 14_ul);
expect(sim.connect(integrator_a.y[0], cross.x[0]) == expect(sim.connect(integrator_a.y[0], cross.x[0]) ==
irt::status::success); irt::status::success);
...@@ -1138,6 +1137,7 @@ main() ...@@ -1138,6 +1137,7 @@ main()
fmt::print(os, "t,v,u\n"); fmt::print(os, "t,v,u\n");
expect(irt::status::success == sim.initialize(t)); expect(irt::status::success == sim.initialize(t));
!expect(sim.sched.size() == 14_ul);
do { do {
irt::status st = sim.run(t); irt::status st = sim.run(t);
......
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