Commit 5dec4126 authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

gui: update observer output type

This patch uses all derivative values from qss 1, 2 or 3 to produce
better output in file and plot. A new file is available (discrete file).
It provides a discrete time output (using a new dt parameter) while the
old only stores all derivative values. (Closes: #32).
parent f0febf01
Pipeline #30024 passed with stage
in 1 minute and 54 seconds
......@@ -353,12 +353,11 @@ editor::free_group(cluster& group) noexcept
log_w.log(7, "delete model %" PRIu64 "\n", id);
sim.deallocate(id);
if (auto* out = plot_outs.try_to_get(
observation_outputs[get_index(id)].plot_id))
plot_outs.free(*out);
if (auto* out = file_outs.try_to_get(
observation_outputs[get_index(id)].file_id))
file_outs.free(*out);
observation_dispatch(
get_index(id),
[this](auto& outs, auto id) { outs.free(id); });
observation_outputs[get_index(id)] = std::monostate{};
}
} else {
auto id = std::get<cluster_id>(child);
......@@ -392,12 +391,11 @@ editor::free_children(const ImVector<int>& nodes) noexcept
parent(id, undefined<cluster_id>());
sim.deallocate(id);
if (auto* out = plot_outs.try_to_get(
observation_outputs[get_index(id)].plot_id))
plot_outs.free(*out);
if (auto* out = file_outs.try_to_get(
observation_outputs[get_index(id)].file_id))
file_outs.free(*out);
observation_dispatch(
get_index(id),
[this](auto& outs, const auto id) { outs.free(id); });
observation_outputs[get_index(id)] = std::monostate{};
}
} else {
const auto id = std::get<cluster_id>(child.first);
......@@ -940,6 +938,8 @@ editor::initialize(u32 id) noexcept
irt_return_if_bad(top.init(to_unsigned(settings.gui_node_cache)));
irt_return_if_bad(plot_outs.init(to_unsigned(settings.kernel_model_cache)));
irt_return_if_bad(file_outs.init(to_unsigned(settings.kernel_model_cache)));
irt_return_if_bad(
file_discrete_outs.init(to_unsigned(settings.kernel_model_cache)));
try {
observation_outputs.resize(sim.models.capacity());
......@@ -2718,68 +2718,93 @@ editor::show_editor() noexcept
if (ImGui::TreeNodeEx(names[i].c_str(),
ImGuiTreeNodeFlags_DefaultOpen)) {
auto& out = observation_outputs[get_index(id)];
auto* plot = plot_outs.try_to_get(out.plot_id);
auto* file = file_outs.try_to_get(out.file_id);
irt_assert(!(file && plot));
int choose = plot ? 1 : file ? 2 : 0;
const auto index = get_index(id);
auto out = observation_outputs[index];
auto old_choose = static_cast<int>(out.index());
auto choose = old_choose;
ImGui::Text("%s",
dynamics_type_names[static_cast<int>(mdl->type)]);
ImGui::RadioButton("none", &choose, 0);
ImGui::SameLine();
ImGui::RadioButton("plot", &choose, 1);
ImGui::SameLine();
ImGui::RadioButton("file", &choose, 2);
const char* items[] = { "none", "plot", "file", "file dt " };
ImGui::Combo("type", &choose, items, IM_ARRAYSIZE(items));
if (choose == 1) {
if (file) {
file_outs.free(*file);
if (old_choose == 2 || old_choose == 3) {
sim.observers.free(mdl->obs_id);
observation_outputs_free(index);
}
if (!plot) {
plot_output* plot;
if (old_choose != 1) {
plot_output& tf = plot_outs.alloc(names[i].c_str());
tf.ed = this;
plot = &tf;
out.plot_id = plot_outs.get_id(tf);
auto& o =
sim.observers.alloc(names[i].c_str(), tf);
tf.ed = this;
observation_outputs[index] = plot_outs.get_id(tf);
auto& o = sim.observers.alloc(names[i].c_str(), tf);
sim.observe(*mdl, o);
} else {
plot =
plot_outs.try_to_get(std::get<plot_output_id>(out));
irt_assert(plot);
}
ImGui::InputText(
"name##plot", plot->name.begin(), plot->name.capacity());
ImGui::InputDouble(
"dt##plot", &plot->time_step, 0.001, 1.0, "%.8f");
} else if (choose == 2) {
if (plot) {
plot_outs.free(*plot);
if (old_choose == 1 || old_choose == 3) {
sim.observers.free(mdl->obs_id);
observation_outputs_free(index);
}
if (!file) {
file_output* file;
if (old_choose != 2) {
file_output& tf = file_outs.alloc(names[i].c_str());
tf.ed = this;
file = &tf;
out.file_id = file_outs.get_id(tf);
auto& o =
sim.observers.alloc(names[i].c_str(), tf);
tf.ed = this;
observation_outputs[index] = file_outs.get_id(tf);
auto& o = sim.observers.alloc(names[i].c_str(), tf);
sim.observe(*mdl, o);
} else {
file =
file_outs.try_to_get(std::get<file_output_id>(out));
irt_assert(file);
}
ImGui::InputText(
"name##file", file->name.begin(), file->name.capacity());
} else {
if (plot) {
plot_outs.free(*plot);
} else if (choose == 3) {
if (old_choose == 1 || old_choose == 2) {
sim.observers.free(mdl->obs_id);
observation_outputs_free(index);
}
if (file) {
file_outs.free(*file);
sim.observers.free(mdl->obs_id);
file_discrete_output* file;
if (old_choose != 3) {
file_discrete_output& tf =
file_discrete_outs.alloc(names[i].c_str());
file = &tf;
tf.ed = this;
observation_outputs[index] =
file_discrete_outs.get_id(tf);
auto& o = sim.observers.alloc(names[i].c_str(), tf);
sim.observe(*mdl, o);
} else {
file = file_discrete_outs.try_to_get(
std::get<file_discrete_output_id>(out));
irt_assert(file);
}
ImGui::InputText("name##filedt",
file->name.begin(),
file->name.capacity());
ImGui::InputDouble(
"dt##filedt", &file->time_step, 0.001, 1.0, "%.8f");
} else if (old_choose != choose) {
sim.observers.free(mdl->obs_id);
observation_outputs_free(index);
}
sim.dispatch(
......
......@@ -220,6 +220,7 @@ struct editor;
enum class plot_output_id : u64;
enum class file_output_id : u64;
enum class file_discrete_output_id : u64;
struct plot_output
{
......@@ -252,7 +253,7 @@ struct file_output
{}
void operator()(const irt::observer& obs,
const irt::dynamics_type /*type*/,
const irt::dynamics_type type,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
......@@ -271,7 +272,7 @@ struct file_discrete_output
{}
void operator()(const irt::observer& obs,
const irt::dynamics_type /*type*/,
const irt::dynamics_type type,
const irt::time tl,
const irt::time t,
const irt::observer::status s);
......@@ -283,19 +284,10 @@ struct file_discrete_output
double time_step = 0.01;
};
struct observation_output
{
constexpr observation_output() = default;
constexpr void clear() noexcept
{
plot_id = undefined<plot_output_id>();
file_id = undefined<file_output_id>();
}
plot_output_id plot_id = undefined<plot_output_id>();
file_output_id file_id = undefined<file_output_id>();
};
using observation_output = std::variant<std::monostate,
plot_output_id,
file_output_id,
file_discrete_output_id>;
struct editor
{
......@@ -325,8 +317,48 @@ struct editor
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;
std::vector<observation_output> observation_outputs;
template<typename Function, typename... Args>
constexpr void observation_dispatch(const u32 index,
Function&& f,
Args... args) noexcept
{
switch (observation_outputs[index].index()) {
case 1:
f(plot_outs,
std::get<plot_output_id>(observation_outputs[index]),
args...);
break;
case 2:
f(file_outs,
std::get<file_output_id>(observation_outputs[index]),
args...);
break;
case 3:
f(file_discrete_outs,
std::get<file_discrete_output_id>(observation_outputs[index]),
args...);
break;
default:
break;
}
}
void observation_outputs_free(const u32 index) noexcept
{
observation_dispatch(index, [](auto& outs, auto out_id) {
outs.free(out_id);
});
observation_outputs[index] = std::monostate{};
}
std::filesystem::path observation_directory;
data_array<cluster, cluster_id> clusters;
......
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