Maintenance - Mise à jour mensuelle Lundi 7 Décembre 2021 entre 7h00 et 9h00

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

gui: global refactor source/header

parent 2ae7644c
......@@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(irritator-gui VERSION 0.1.0 LANGUAGES CXX)
set(gui_sources
dialog-file.cpp gui.cpp gui.hpp imnodes.cpp imnodes.hpp implot.h implot.cpp
window-logger.cpp node-editor.hpp node-editor.cpp simulation-editor.cpp
sources.cpp
application.cpp application.hpp dialog.cpp dialog.hpp imnodes.cpp
imnodes.hpp implot.h implot.cpp internal.hpp internal.cpp node-editor.hpp
node-editor.cpp simulation-editor.cpp sources.cpp window-logger.cpp
${PROJECT_SOURCE_DIR}/../../external/imgui/imgui.cpp
${PROJECT_SOURCE_DIR}/../../external/imgui/imgui.h
${PROJECT_SOURCE_DIR}/../../external/imgui/imgui_demo.cpp
......
// Copyright (c) 2020 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "application.hpp"
#include "dialog.hpp"
#include "node-editor.hpp"
#include <irritator/core.hpp>
#include <chrono>
namespace irt {
bool application::init()
{
if (auto ret = editors.init(50u); is_bad(ret)) {
log_w.log(2, "Fail to initialize irritator: %s\n", status_string(ret));
std::fprintf(stderr, "Fail to initialize irritator: %s\n", status_string(ret));
return false;
}
if (auto* ed = app.alloc_editor(); ed) {
ed->context = imnodes::EditorContextCreate();
ed->settings.compute_colors();
}
try {
if (auto home = get_home_directory(); home) {
home_dir = home.value();
home_dir /= "irritator";
} else {
log_w.log(
3,
"Fail to retrieve home directory. Use current directory instead");
home_dir = std::filesystem::current_path();
}
if (auto install = get_executable_directory(); install) {
executable_dir = install.value();
} else {
log_w.log(
3,
"Fail to retrieve executable directory. Use current directory "
"instead");
executable_dir = std::filesystem::current_path();
}
log_w.log(5,
"home: %s\ninstall: %s\n",
home_dir.u8string().c_str(),
executable_dir.u8string().c_str());
return true;
} catch (const std::exception& /*e*/) {
log_w.log(2, "Fail to initialize application");
return false;
}
}
bool
void application::show()
{
bool ret = true;
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("New")) {
if (auto* ed = alloc_editor(); ed)
ed->context = imnodes::EditorContextCreate();
}
ImGui::Separator();
if (ImGui::MenuItem("Quit"))
ret = false;
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Window")) {
editor* ed = nullptr;
while (editors.next(ed))
ImGui::MenuItem(ed->name.c_str(), nullptr, &ed->show);
ImGui::MenuItem("Simulation", nullptr, &show_simulation);
ImGui::MenuItem("Plot", nullptr, &show_plot);
ImGui::MenuItem("Sources", nullptr, &show_sources_window);
ImGui::MenuItem("Settings", nullptr, &show_settings);
ImGui::MenuItem("Log", nullptr, &show_log);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help")) {
ImGui::MenuItem("Demo window", nullptr, &show_demo);
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
editor* ed = nullptr;
while (editors.next(ed)) {
if (ed->show) {
if (!ed->show_editor()) {
editor* next = ed;
editors.next(next);
free_editor(*ed);
} else {
if (ed->show_settings)
ed->settings.show(&ed->show_settings);
}
}
}
if (show_simulation)
show_simulation_window();
if (show_plot)
show_plot_window();
if (show_log)
log_w.show(&show_log);
if (show_settings)
settings.show(&show_settings);
if (show_demo)
ImGui::ShowDemoWindow();
if (show_sources_window)
show_sources(&show_sources_window);
return ret;
}
editor*
application::alloc_editor()
{
if (srcs.binary_file_sources.capacity() == 0) {
srcs.init(50);
}
if (!editors.can_alloc(1u)) {
log_w.log(2, "Too many open editor\n");
return nullptr;
}
auto& ed = editors.alloc();
if (auto ret = ed.initialize(get_index(editors.get_id(ed))); is_bad(ret)) {
log_w.log(2, "Fail to initialize irritator: %s\n", status_string(ret));
editors.free(ed);
return nullptr;
}
log_w.log(5, "Open editor %s\n", ed.name.c_str());
return &ed;
}
void
application::free_editor(editor& ed)
{
log_w.log(5, "Close editor %s\n", ed.name.c_str());
editors.free(ed);
}
void
application::show_plot_window()
{
ImGui::SetNextWindowPos(ImVec2(50, 400), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(600, 350), ImGuiCond_Once);
if (!ImGui::Begin("Plot", &show_plot)) {
ImGui::End();
return;
}
static editor_id current = undefined<editor_id>();
if (auto* ed = make_combo_editor_name(*this, current); ed) {
if (ImPlot::BeginPlot("simulation", "t", "s")) {
ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, 1.f);
plot_output* out = nullptr;
while (ed->plot_outs.next(out)) {
if (!out->xs.empty() && !out->ys.empty())
ImPlot::PlotLine(out->name.c_str(),
out->xs.data(),
out->ys.data(),
static_cast<int>(out->xs.size()));
}
ImPlot::PopStyleVar(1);
ImPlot::EndPlot();
}
}
ImGui::End();
}
void application::show_settings_window()
{
ImGui::SetNextWindowPos(ImVec2(300, 300), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(350, 400), ImGuiCond_Once);
if (!ImGui::Begin("Settings", &show_settings)) {
ImGui::End();
return;
}
ImGui::Text("Home.......: %s", home_dir.u8string().c_str());
ImGui::Text("Executable.: %s", executable_dir.u8string().c_str());
ImGui::End();
}
void
application::shutdown()
{
editor* ed = nullptr;
while (editors.next(ed))
imnodes::EditorContextFree(ed->context);
}
static status
simulation_run_for(simulation& sim,
long long int duration_in_microseconds,
const double end,
double& current) noexcept
{
namespace stdc = std::chrono;
auto start_at = stdc::high_resolution_clock::now();
long long int duration_since_start;
do {
if (sim.current_status = sim.run(current); is_bad(sim.current_status))
return ret;
auto end_at = stdc::high_resolution_clock::now();
auto duration = end_at - start_at;
auto duration_cast = stdc::duration_cast<stdc::microseconds>(duration);
duration_since_start = duration_cast.count();
} while (duration_since_start < duration_in_microseconds);
return status::success;
}
void application::run_simulations()
{
int running_simulation = 0;
editor* ed = nullptr;
while (editors.next(ed))
if (ed->st = editor_status::running)
++running_simulation;
if (!running_simulation)
return;
auto duration = 10000 / running_simulation;
ed = nullptr;
while (editors.next(ed))
if (ed->st = editor_status::running)
ed->sim_st = run_for(ed->sim, duration, ed->simulation_end, ed->simulation_current);
}
} // namespace irt
// Copyright (c) 2020 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ORG_VLEPROJECT_IRRITATOR_APP_APPLICATION_2021
#define ORG_VLEPROJECT_IRRITATOR_APP_APPLICATION_2021
#include <irritator/core.hpp>
#include <irritator/external_source.hpp>
#include <filesystem>
#include <optional>
namespace irt {
struct application;
struct editor;
struct application
{
data_array<editor, editor_id> editors;
std::filesystem::path home_dir;
std::filesystem::path executable_dir;
external_source srcs;
bool show_log = true;
bool show_simulation = true;
bool show_demo = false;
bool show_plot = true;
bool show_settings = false;
bool show_sources_window = false;
bool init();
bool show();
void shutdown();
// For each editor run the simulation. Use this function outside of the
// ImGui::Render/NewFrame to not block the graphical user interface.
void run_simulations();
void show_sources(bool* is_show);
void show_menu_sources(const char* title, source& src);
void show_plot_window();
void show_simulation_window();
void show_settings_window();
editor* alloc_editor();
void free_editor(editor& ed);
};
} // namespace irt
#endif
......@@ -124,41 +124,6 @@ get_executable_directory()
}
#endif
application::settings_manager::settings_manager() noexcept
{
try {
if (auto home = get_home_directory(); home) {
home_dir = home.value();
home_dir /= "irritator";
} else {
log_w.log(
3,
"Fail to retrieve home directory. Use current directory instead");
home_dir = std::filesystem::current_path();
}
if (auto install = get_executable_directory(); install) {
executable_dir = install.value();
} else {
log_w.log(
3,
"Fail to retrieve executable directory. Use current directory "
"instead");
executable_dir = std::filesystem::current_path();
}
log_w.log(5,
"home: %s\ninstall: %s\n",
home_dir.u8string().c_str(),
executable_dir.u8string().c_str());
// TODO Fill the libraries vectors with users and systems directory.
} catch (const std::exception& /*e*/) {
log_w.log(2, "Fail to initialize application");
}
}
struct file_dialog
{
std::vector<std::filesystem::path> paths;
......
......@@ -2,33 +2,13 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ORG_VLEPROJECT_IRRITATOR_APP_GUI_2020
#define ORG_VLEPROJECT_IRRITATOR_APP_GUI_2020
#ifndef ORG_VLEPROJECT_IRRITATOR_APP_DIALOG_2021
#define ORG_VLEPROJECT_IRRITATOR_APP_DIALOG_2021
#include <filesystem>
#include <optional>
namespace irt {
// Forward declarations
struct simulation;
void
application_initialize();
bool
application_show();
void
application_shutdown();
void
simulation_run_for(simulation& sim,
const long long int duration_in_microseconds,
const double end,
double& current);
/* Move into internal API */
namespace irt {
std::optional<std::filesystem::path>
get_home_directory();
......@@ -36,8 +16,6 @@ get_home_directory();
std::optional<std::filesystem::path>
get_executable_directory();
/* Filesytem dialog box */
bool
load_file_dialog(std::filesystem::path& out,
const char* title,
......@@ -51,6 +29,6 @@ save_file_dialog(std::filesystem::path& out,
bool
select_directory_dialog(std::filesystem::path& out);
} // namespace irt
}
#endif
#endif
\ No newline at end of file
// Copyright (c) 2020 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "internal.hpp"
namespace irt {
void
HelpMarker(const char* desc) noexcept;
{
try {
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
} catch (const std::exception& /*e*/) {
}
}
const char*
status_string(const status s) noexcept
{
static const char* str[] = {
"success",
"unknown_dynamics",
"block_allocator_bad_capacity",
"block_allocator_not_enough_memory",
"head_allocator_bad_capacity",
"head_allocator_not_enough_memory",
"simulation_not_enough_model",
"simulation_not_enough_memory_message_list_allocator",
"simulation_not_enough_memory_input_port_list_allocator",
"simulation_not_enough_memory_output_port_list_allocator",
"data_array_init_capacity_error",
"data_array_not_enough_memory",
"data_array_archive_init_capacity_error",
"data_array_archive_not_enough_memory",
"array_init_capacity_zero",
"array_init_capacity_too_big",
"array_init_not_enough_memory",
"vector_init_capacity_zero",
"vector_init_capacity_too_big",
"vector_init_not_enough_memory",
"source_unknown_id",
"source_empty",
"dynamics_unknown_id",
"dynamics_unknown_port_id",
"dynamics_not_enough_memory",
"model_connect_output_port_unknown",
"model_connect_input_port_unknown",
"model_connect_already_exist",
"model_connect_bad_dynamics",
"model_queue_bad_ta",
"model_queue_empty_allocator",
"model_queue_full",
"model_dynamic_queue_source_is_null",
"model_dynamic_queue_empty_allocator",
"model_dynamic_queue_full",
"model_priority_queue_source_is_null",
"model_priority_queue_empty_allocator",
"model_priority_queue_full",
"model_integrator_dq_error",
"model_integrator_X_error",
"model_integrator_internal_error",
"model_integrator_output_error",
"model_integrator_running_without_x_dot",
"model_integrator_ta_with_bad_x_dot",
"model_generator_null_ta_source",
"model_generator_empty_ta_source",
"model_generator_null_value_source",
"model_generator_empty_value_source",
"model_quantifier_bad_quantum_parameter",
"model_quantifier_bad_archive_length_parameter",
"model_quantifier_shifting_value_neg",
"model_quantifier_shifting_value_less_1",
"model_time_func_bad_init_message",
"model_flow_bad_samplerate",
"model_flow_bad_data",
"gui_not_enough_memory",
"io_not_enough_memory",
"io_file_format_error",
"io_file_format_source_number_error",
"io_file_source_full",
"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"
};
static_assert(std::size(str) == status_size());
return str[static_cast<int>(s)];
}
} // namespace irt
// Copyright (c) 2020 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ORG_VLEPROJECT_IRRITATOR_APP_INTERNAL_2020
#define ORG_VLEPROJECT_IRRITATOR_APP_INTERNAL_2020
#include <irritator/core.hpp>
#include <fmt/format.h>
namespace irt {
/// Helper to display a little (?) mark which shows a tooltip when hovered. In
/// your own code you may want to display an actual icon if you are using a
/// merged icon fonts (see docs/FONTS.md)
inline void
HelpMarker(const char* desc) noexcept;
/// Return the description string for each status.
inline const char*
status_string(const status s) noexcept;
/// Helper to assign fmtlib format string to a small_string.
template<size_t N, typename... Args>
void
format(small_string<N>& str, const char* fmt, const Args&... args)
{
auto ret = fmt::format_to_n(str.begin(), N - 1, fmt, args...);
str.size(ret.size);
}
} // namespace irt
#endif
......@@ -48,14 +48,6 @@ editor::settings_manager::compute_colors() noexcept
ImGui::ColorConvertFloat4ToU32(gui_cluster_color * 1.5f);
}
template<size_t N, typename... Args>
void
format(small_string<N>& str, const char* fmt, const Args&... args)
{
auto ret = fmt::format_to_n(str.begin(), N - 1, fmt, args...);
str.size(ret.size);
}
void
editor::clear() noexcept
{
......@@ -3105,55 +3097,6 @@ editor::show_editor() noexcept
return true;
}
editor*
application::alloc_editor()
{
if (srcs.binary_file_sources.capacity() == 0) {
srcs.init(50);
}
if (!editors.can_alloc(1u)) {
log_w.log(2, "Too many open editor\n");
return nullptr;
}
auto& ed = editors.alloc();
if (auto ret = ed.initialize(get_index(editors.get_id(ed))); is_bad(ret)) {
log_w.log(2, "Fail to initialize irritator: %s\n", status_string(ret));
editors.free(ed);
return nullptr;
}
log_w.log(5, "Open editor %s\n", ed.name.c_str());
return &ed;
}
void
application::free_editor(editor& ed)
{
log_w.log(5, "Close editor %s\n", ed.name.c_str());
editors.free(ed);
}