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

WIP

parent 2c7912e4
Pipeline #40314 failed with stage
in 59 seconds
......@@ -5,6 +5,7 @@ set(gui_sources
application.cpp application.hpp dialog.cpp dialog.hpp imnodes.cpp
imnodes.h imnodes_internal.h implot.h implot.cpp internal.hpp internal.cpp
node-editor.cpp simulation-editor.cpp sources.cpp window-logger.cpp
${PROJECT_SOURCE_DIR}/../../lib/modeling.cpp
${PROJECT_SOURCE_DIR}/../../external/imgui/imgui.cpp
${PROJECT_SOURCE_DIR}/../../external/imgui/imgui.h
${PROJECT_SOURCE_DIR}/../../external/imgui/imgui_demo.cpp
......
......@@ -72,20 +72,19 @@ struct plot_output
: name(name_)
{}
editor* ed = nullptr;
editor* ed = nullptr;
std::vector<float> xs;
std::vector<float> ys;
small_string<24u> name;
real tl = zero;
real time_step = to_real(0.01);
small_string<24u> name;
real tl = zero;
real time_step = to_real(0.01);
};
void
plot_output_callback(const irt::observer& obs,
const irt::dynamics_type /*type*/,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
void plot_output_callback(const irt::observer& obs,
const irt::dynamics_type /*type*/,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
struct file_output
{
......@@ -95,17 +94,16 @@ struct file_output
: name(name_)
{}
editor* ed = nullptr;
std::ofstream ofs;
editor* ed = nullptr;
std::ofstream ofs;
small_string<24u> name;
};
void
file_output_callback(const irt::observer& obs,
const irt::dynamics_type type,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
void file_output_callback(const irt::observer& obs,
const irt::dynamics_type type,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
struct file_discrete_output
{
......@@ -115,60 +113,56 @@ struct file_discrete_output
: name(name_)
{}
editor* ed = nullptr;
std::ofstream ofs;
editor* ed = nullptr;
std::ofstream ofs;
small_string<24u> name;
real tl = irt::real(0);
real time_step = irt::real(0.01);
real tl = irt::real(0);
real time_step = irt::real(0.01);
};
void
file_discrete_output_callback(const irt::observer& obs,
const irt::dynamics_type type,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
void file_discrete_output_callback(const irt::observer& obs,
const irt::dynamics_type type,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
int
make_input_node_id(const irt::model_id mdl, const int port) noexcept;
int make_input_node_id(const irt::model_id mdl, const int port) noexcept;
int
make_output_node_id(const irt::model_id mdl, const int port) noexcept;
int make_output_node_id(const irt::model_id mdl, const int port) noexcept;
std::pair<irt::u32, irt::u32>
get_model_input_port(const int node_id) noexcept;
std::pair<irt::u32, irt::u32> get_model_input_port(const int node_id) noexcept;
std::pair<irt::u32, irt::u32>
get_model_output_port(const int node_id) noexcept;
std::pair<irt::u32, irt::u32> get_model_output_port(const int node_id) noexcept;
struct editor
{
small_string<16> name;
small_string<16> name;
std::filesystem::path path;
ImNodesEditorContext* context = nullptr;
bool show = true;
bool show_minimap = true;
ImNodesEditorContext* context = nullptr;
bool show = true;
bool show_minimap = true;
simulation sim;
simulation sim;
external_source srcs;
irt::real simulation_begin = 0;
irt::real simulation_end = 10;
irt::real simulation_current = 10;
irt::real simulation_begin = 0;
irt::real simulation_end = 10;
irt::real simulation_current = 10;
irt::real simulation_next_time = 0;
long simulation_bag_id = 0;
int step_by_step_bag = 0;
long simulation_bag_id = 0;
int step_by_step_bag = 0;
real simulation_during_date;
int simulation_during_bag;
int simulation_during_bag;
editor_status st = editor_status::editing;
status sim_st = status::success;
editor_status st = editor_status::editing;
status sim_st = status::success;
editor() noexcept;
~editor() noexcept;
bool is_running() const noexcept
bool
is_running() const noexcept
{
return match(st,
editor_status::running,
......@@ -178,18 +172,17 @@ struct editor
}
bool simulation_show_value = false;
bool stop = false;
bool stop = false;
data_array<plot_output, plot_output_id> plot_outs;
data_array<file_output, file_output_id> file_outs;
data_array<file_discrete_output, file_discrete_output_id>
file_discrete_outs;
file_discrete_outs;
std::vector<observation_output> observation_outputs;
template<typename Function, typename... Args>
constexpr void observation_dispatch(const u32 index,
Function&& f,
Args... args) noexcept
constexpr void
observation_dispatch(const u32 index, Function&& f, Args... args) noexcept
{
switch (observation_outputs[index].index()) {
case 1:
......@@ -215,7 +208,8 @@ struct editor
}
}
void observation_outputs_free(const u32 index) noexcept
void
observation_outputs_free(const u32 index) noexcept
{
observation_dispatch(
index, [](auto& outs, auto out_id) { outs.free(out_id); });
......@@ -230,22 +224,22 @@ struct editor
ImVector<ImVec2> positions;
ImVector<ImVec2> displacements;
bool use_real_time;
bool starting = true;
bool use_real_time;
bool starting = true;
float synchronize_timestep = 1.f;
std::string tooltip;
bool show_load_file_dialog = false;
bool show_save_file_dialog = false;
bool show_load_file_dialog = false;
bool show_save_file_dialog = false;
bool show_select_directory_dialog = false;
bool show_settings = false;
bool show_settings = false;
struct settings_manager
{
int kernel_model_cache = 1024;
int kernel_message_cache = 32768;
int gui_node_cache = 1024;
int kernel_model_cache = 1024;
int kernel_message_cache = 32768;
int gui_node_cache = 1024;
ImVec4 gui_model_color{ .27f, .27f, .54f, 1.f };
ImVec4 gui_model_transition_color{ .27f, .54f, .54f, 1.f };
......@@ -254,11 +248,11 @@ struct editor
ImU32 gui_hovered_model_transition_color;
ImU32 gui_selected_model_transition_color;
int automatic_layout_iteration_limit = 200;
float automatic_layout_x_distance = 350.f;
float automatic_layout_y_distance = 350.f;
float grid_layout_x_distance = 250.f;
float grid_layout_y_distance = 250.f;
int automatic_layout_iteration_limit = 200;
float automatic_layout_x_distance = 350.f;
float automatic_layout_y_distance = 350.f;
float grid_layout_x_distance = 250.f;
float grid_layout_y_distance = 250.f;
bool show_dynamics_inputs_in_editor = false;
......@@ -268,9 +262,9 @@ struct editor
} settings;
status initialize(u32 id) noexcept;
void clear() noexcept;
void clear() noexcept;
void free_children(const ImVector<int>& nodes) noexcept;
void free_children(const ImVector<int>& nodes) noexcept;
status copy(const ImVector<int>& nodes) noexcept;
void compute_grid_layout() noexcept;
......@@ -285,22 +279,24 @@ struct editor
, port_index(port_index_)
{}
irt::model* model = nullptr;
int port_index = 0;
irt::model* model = nullptr;
int port_index = 0;
};
gport get_in(const int index) noexcept
gport
get_in(const int index) noexcept
{
const auto model_index_port = get_model_input_port(index);
auto* mdl = sim.models.try_to_get(model_index_port.first);
auto* mdl = sim.models.try_to_get(model_index_port.first);
return { mdl, static_cast<int>(model_index_port.second) };
}
gport get_out(const int index) noexcept
gport
get_out(const int index) noexcept
{
const auto model_index_port = get_model_output_port(index);
auto* mdl = sim.models.try_to_get(model_index_port.first);
auto* mdl = sim.models.try_to_get(model_index_port.first);
return { mdl, static_cast<int>(model_index_port.second) };
}
......@@ -322,11 +318,11 @@ struct window_logger
{
ImGuiTextBuffer buffer;
ImGuiTextFilter filter;
ImVector<int> line_offsets;
ImVector<int> line_offsets;
bool auto_scroll = true;
bool auto_scroll = true;
bool scroll_to_bottom = false;
window_logger() = default;
window_logger() = default;
void clear() noexcept;
void log(const int level, const char* fmt, ...) IM_FMTARGS(3);
......@@ -334,21 +330,23 @@ struct window_logger
void show(bool* is_show);
};
const char*
log_string(const log_status s) noexcept;
const char* log_string(const log_status s) noexcept;
struct component
{};
struct application
{
data_array<editor, editor_id> editors;
std::filesystem::path home_dir;
std::filesystem::path executable_dir;
std::vector<long long int> simulation_duration;
std::filesystem::path home_dir;
std::filesystem::path executable_dir;
std::vector<long long int> simulation_duration;
bool show_log = true;
bool show_log = true;
bool show_simulation = true;
bool show_demo = false;
bool show_plot = true;
bool show_settings = false;
bool show_demo = false;
bool show_plot = true;
bool show_settings = false;
bool init();
bool show();
......@@ -363,7 +361,7 @@ struct application
void show_settings_window();
editor* alloc_editor();
void free_editor(editor& ed);
void free_editor(editor& ed);
editor* make_combo_editor_name(editor_id& id) noexcept;
};
......
......@@ -10,29 +10,32 @@
namespace irt {
enum class component_id = u64;
enum class parameter_id = u64;
enum class component_id = u64;
enum class component_ref_id = u64;
enum class parameter_id = u64;
struct edge;
struct vertices;
enum class vertice_type : i8
{
model, component;
};
struct parameter;
struct connection;
struct child;
struct port;
struct component;
struct component_ref;
struct modeling;
enum class edge_type : i8
status build_simulation(const modeling& mod, simulation& sim);
struct parameter
{
model, component;
u64 integer[8];
real values[8];
};
status add_model(modeling& m, component& parent, model& mdl);
status add_component(modeling& m, component& parent, component& comp);
void destroy_vertice(modeling& m, component& parent, int index);
void unref_vertice(modeling& m, component& parent, int index);
status add_edge(modeling& m, const port& src, const port& dst);
void destroy_edge(modeling& m, component& c, int index);
status compute_simulation(modeling& m, simulation& sim);
struct edge
struct connection
{
u64 src; // model_id or component_id
u64 dst; // model_id or component_id
......@@ -42,14 +45,29 @@ struct edge
i8 port_dst; // input port index
};
struct vertice
struct component_ref
{
u64 id; // model_id or component_id
component_id id; // the component reference
vector<parameter_id> parameters; // same number as configurables
vector<observer_id> observers; // same number as observable
table<model_id, model_id> mappers;
hierarchy<component_ref> tree;
};
struct child
{
child(model_id model) noexcept;
child(component_ref_id component) noexcept;
u64 id;
node_type type;
};
struct port
{
port(model_id model, i8 port) noexcept;
port(component_ref_id component, i8 port) noexcept;
u64 id;
node_type type;
i8 port;
......@@ -57,25 +75,50 @@ struct port
struct component
{
vector<vertice> vertices;
vector<edge> edges;
vector<port> x;
vector<port> y;
hierarchy<component> tree;
vector<child> children;
vector<connection> connections;
vector<vertice> parameters;
vector<vertice> observables;
vector<port> x;
vector<port> y;
vector<child> configurables; // configurable model list
vector<child> observables; // observable model list
};
struct modeling
{
small_string<16> name;
data_array<model, model_id> models;
data_array<component_ref, component_ref_id> components;
data_array<component, component_id> components;
data_array<parameter, parameter_id> parameters;
data_array<observer, observer_id> observers;
data_array<component, component_id> components;
data_array<model, model_id> models;
component_ref_id head = component_ref_id{ 0 };
};
////
inline child::child(model_id model) noexcept
: id{ ordinal(model) }
, type{ child_type::model }
{}
inline child::child(component_ref_id component) noexcept
: id{ ordinal(component) }
, type{ child_type::component }
{}
inline port::port(model_id model, i8 port) noexcept
: id{ ordinal(model) }
, type{ child_type::model }
, port(port_)
{}
inline port::port(component_ref_id component, i8 port) noexcept
: id{ ordinal(component) }
, type{ child_type::component }
, port(port_)
{}
} // namespace irt
#endif
......@@ -6,218 +6,69 @@
namespace irt {
static void destroy_model(modeling& m, model& m);
static void destroy_component(modeling& m, component& c);
static bool is_input_port_exist(modeling& m,
component& parent,
int index,
i8 port);
static bool is_output_port_exist(modeling& m,
component& parent,
int index,
i8 port);
status
add_model(modeling& m, component& parent, model& mdl)
static status
build_models(const modeling& mod, const component_ref& comp, simulation& sim)
{
auto ret = status::success;
auto mdl_id = m.models.get_id(mdl);
if (parent.vertices.can_alloc(1)) {
irt_return_if_bad(parent.vertice.try_emplace_back());
auto& vertice = parent.back();
vertice.id = ordinal(mdl_id);
vectice.type = vertice_type::model;
} else {
ret = status::simulation_not_enough_model;
}
comp.mappers.clear();
return ret;
}
status
add_component(modeling& m, component& parent, component& comp)
{
auto ret = status::success;
auto comp_id = m.components.get_id(comp);
if (parent.vertices.can_alloc(1)) {
irt_return_if_bad(parent.vertice.try_emplace_back());
auto& vertice = parent.back();
vertice.id = ordinal(comp_id);
vertice.type = vertice_type::component;
com.parent_to(parent.d);
} else {
ret = status::simulation_not_enough_model;
}
for (i64 i = 0, e = comp.children.size(); i != e; ++i) {
u64 id = comp.children[i].id;
return ret;
}
if (comp.children[i].type == child_type::model) {
auto src_id = enum_cast<model_id>(id);
auto* src = mod.models.try_to_get(src_id);
if (!src)
continue;
void
destroy_vertice(modeling& m, component& parent, int index)
{
irt_assert(index >= 0 && index < c.vertices.size());
irt_return_if_fail(sim.models.can_alloc(1),
status::simulation_not_enough_model);
u64 id = parent.vertices[index].id;
auto& dst = sim.models.clone(*src);
auto dst_id = sim.models.get_id(dst);
if (parent.vertices[index].type == vertice_type::model) {
auto mdl_id = to_enum<model_id>(id);
if (auto* mdl = m.models.try_to_get(mdl_id); mdl) {
destroy_model(*mdl);
}
} else {
auto compo_id = to_enum<component_id>(id);
if (auto* compo = m.components.try_to_get(compo_id); compo) {
destroy_component(m, *compo);
}
}
c.vertices.pop_and_swap(index);
}
void
unref_vertice(modeling& m, component& parent, int index)
{
irt_assert(index >= 0 && index < c.vertices.size());
u64 id = parent.vertices[index].id;
comp.mappers.data.emplace_back(src_id, dst_id);
} else {
auto src_id = enum_cast<component_ref_id>(id);
auto* src = mod.component_refs.try_to_get(src_id);
if (!src)
continue;
if (parent.vertices[index].type == vertice_type::model) {
auto mdl_id = to_enum<model_id>(id);
if (auto* mdl = m.models.try_to_get(mdl_id); mdl) {
destroy_model(*mdl);
irt_return_if_bad(build_models(mod, *src, sim));
}
}
c.vertices.pop_and_swap(index);
}
status
add_edge(modeling& m,
component& parent,
int index_src,
int index_dst,
i8 port_src,
i8 port_dst)
{
irt_assert(index_src >= 0 && index_src < c.vertices.size());
irt_assert(index_dst >= 0 && index_dst < c.vertices.size());
auto ret = status::success;
auto& edge = parent.edges.emplace_back();
edge.src = parent.vertices[index_src].id;
edge.dst = parent.vertices[index_dst].id;
edge.type_src = parent.vertices[index_src].type;
edge.type_dst = parent.vertices[index_dst].type;
edge.port_src = port_src;
edge.port_dst = port_dst;
return ret;
}
void
destroy_edge(modeling& m, component& c, int index)
{
irt_assert(index >= 0 && index < c.edges.size());
c.edges.pop_and_swap(index);
}
com.mappers.sort();
<