add intefaces plugins

This commit is contained in:
2026-03-20 14:44:16 +03:00
parent e59fd990a1
commit cfa39f850b
18 changed files with 723 additions and 87 deletions

187
plugin.hpp Normal file
View File

@@ -0,0 +1,187 @@
#pragma once
#include "monitor/utils/plugins/plugin.hpp"
namespace monitor::utils
{
struct raw_plugin : public plugin
{
public:
enum class TYPE
{
RAW_DATA,
MAGNITUDE,
ENERGY
};
public:
hr::result m_result;
TYPE m_type;
std::string m_display_name;
public:
struct graph
{
public:
// градуировка осьи X
hr::fvec_t m_ox;
// максимальное значение по оси Y
double m_max_element = 0.0;
// размер данных дял отрисовки
std::size_t m_size = 0;
// кол-во линий графика
std::size_t m_line_count = 0;
// тут кол-во графиков на массив данных из этих графиков т.е.:
// [1] = [1, 2, ..., 1'000'000'000]
// [2] = [1, 2, ..., 1'000'000'000]
std::vector<hr::fvec_t> m_data;
// говорит нужно ли делать сжатие графика ли нет
bool m_is_scale = false;
void fill_ox(std::size_t start_pos = 0)
{
m_ox.clear();
for (std::size_t i = start_pos; i < start_pos + m_size; ++i) m_ox.push_back(i);
}
void init()
{
m_data.reserve(m_line_count);
m_ox.reserve(m_size);
for (std::size_t i = 0; i < m_line_count; ++i) m_data.push_back(hr::fvec_t(m_size, 0.f));
}
} m_graph;
public:
bool empty() { return m_result.empty(); }
void graph_init()
{
try
{
auto raw_size = m_result.size();
if (raw_size == 0) throw std::invalid_argument("Error set data in plugin: empty data");
m_graph.m_is_scale = raw_size > var::MAX_RENDER_SIZE;
m_graph.m_size = std::min(raw_size, var::MAX_RENDER_SIZE);
m_graph.m_line_count = m_result.m_data.size();
m_graph.init();
m_graph.fill_ox();
}
catch(std::exception& e)
{
hack::error()(e.what());
}
}
// этот метод запускается один раз при первом рендеринге
// для заполнения начальными данными
void fill()
{
if (m_graph.m_is_scale)
{
m_step = m_result.size() / m_graph.m_size + 1;
std::size_t line_count = 0;
for (auto& gd : m_graph.m_data)
{
std::size_t index = 0;
for (auto& g : gd)
{
float tmp_e = 0.f;
for (std::size_t j = index - m_step; j < index; ++j)
{
auto e = m_result.m_data[line_count][j].m_value;
tmp_e = hack::math::max_abs(e, tmp_e);
}
g = tmp_e;
m_graph.m_max_element = std::fabs(hack::math::max_abs(g, m_graph.m_max_element));
index += m_step;
if (index > m_result.size()) index = m_result.size();
}
++line_count;
}
}
else
{
// заполняется, когда данных пришло меньше чем нужно для полного рендеринга
std::size_t graph_count = 0;
for (auto el : m_result.m_data)
{
std::size_t index = 0;
for (auto e : el)
{
m_graph.m_max_element = hack::math::max(e.m_value, m_graph.m_max_element);
m_graph.m_data[graph_count][index] = e.m_value;
++index;
}
++graph_count;
}
}
}
std::size_t m_local_k2 = 0;
std::size_t m_step;
bool is_scale()
{
return m_graph.m_is_scale;
}
// Это основной меод вычисления данных, которые нужно отрисовать
// 1. Проверяем размер сырых данных
// - если их больше чем var::MAX_RENDER_SIZE, то делаем сжатие
// - если их меньше, то отрисовка идет полностью и fill_ox уже заполнен так как надо и при масштабировании ни чего не пересчитывается is_scale
void fill(ImPlotRect current_limits)
{
// кол-во данных, которые мы сейчас хотим отрисовать, когда поменяли масштаб
auto total_dots_for_render = current_limits.Size().x;
// тоже, что начальный m_step, но если m_step меняется, то этот постоянный
// т.е. это максимальный коефиниент сужения графика
std::size_t k1 = m_result.size() / m_graph.m_size + 1;
// на сколько изменилось кол-во точек, которые нужно отрисовать
std::size_t k2 = var::MAX_RENDER_SIZE / total_dots_for_render - 1.f;
// стэк условий, котолрые ограничивают лишние расчеты и сохраняют текущие данные
if (k1 <= k2 && k2 != 0) return;
if (m_local_k2 == k2 && k2 != 0) return;
m_local_k2 = k2;
// сколько сместилось точке отрисовки во время масштабирования за экран (влево)
std::size_t skip_dots = current_limits.Min().x;
// кол-во точек, которые нужно пропустить из сырых данных чтобы они не были отрисованы во время масштабирования
std::size_t pos = skip_dots * (m_step + k2);
// шаг пропуска, по которому делаем сужение графика
m_step = k1 - k2;
std::size_t line_count = 0;
for (auto& gd : m_graph.m_data)
{
std::size_t index = pos;
for (auto& g : gd)
{
float tmp_e = 0.f;
for (std::size_t j = index - m_step; j < index; ++j)
{
auto e = m_result.m_data[line_count][j].m_value;
// основной критерий сужения: берем максимальный элемент из данного интервала m_step
tmp_e = hack::math::max_abs(e, tmp_e);
}
g = tmp_e;
m_graph.m_max_element = std::fabs(hack::math::max_abs(g, m_graph.m_max_element));
index += m_step;
if (index > m_result.size()) index = m_result.size();
}
++line_count;
}
// нужно передать смещение для установки градации
m_graph.fill_ox(skip_dots);
}
};
}