chore: sync from fn-registry agent
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
// Demos faltantes: process_runner (Core), candlestick / gauge / heatmap /
|
||||
// table_view (Viz). Aniade cobertura sobre los primitivos del registry que
|
||||
// no tenian su entry en la gallery.
|
||||
|
||||
#include "demos.h"
|
||||
#include "demo.h"
|
||||
|
||||
#include "core/process_runner.h"
|
||||
#include "viz/candlestick.h"
|
||||
#include "viz/gauge.h"
|
||||
#include "viz/heatmap.h"
|
||||
#include "viz/table_view.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace gallery {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// process_runner (Core)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_process_runner() {
|
||||
demo_header("process_runner", "v1.0.0",
|
||||
"Ejecuta una tarea en std::thread en background y expone estado thread-safe "
|
||||
"(idle/running/success/error). El widget runner_status() dibuja inline un "
|
||||
"spinner mientras corre y un mensaje de Success/Error al terminar.");
|
||||
|
||||
static fn_ui::ProcessRunner runner;
|
||||
|
||||
section("Tarea simulada (sleep 2s)");
|
||||
{
|
||||
if (ImGui::Button("Run task")) {
|
||||
if (!runner.is_busy()) {
|
||||
fn_ui::runner_trigger(runner, [](std::string& out) -> bool {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
out = "task done in 2s";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Run failing task")) {
|
||||
if (!runner.is_busy()) {
|
||||
fn_ui::runner_trigger(runner, [](std::string& out) -> bool {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
out = "simulated failure";
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Reset")) runner.reset();
|
||||
fn_ui::runner_status(runner, "Working...");
|
||||
}
|
||||
|
||||
code_block(
|
||||
"static fn_ui::ProcessRunner r;\n"
|
||||
"if (button(\"Run\", Primary) && !r.is_busy()) {\n"
|
||||
" fn_ui::runner_trigger(r, [](std::string& out) -> bool {\n"
|
||||
" return do_work(&out);\n"
|
||||
" });\n"
|
||||
"}\n"
|
||||
"fn_ui::runner_status(r, \"Working...\");"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// candlestick (Viz)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_candlestick() {
|
||||
demo_header("candlestick", "v1.0.0",
|
||||
"Grafico de velas OHLC con ImPlot custom rendering. Verde si close >= open, "
|
||||
"rojo si bajista. Tooltip al hover muestra OHLC del dia.");
|
||||
|
||||
section("OHLC sintetico (30 dias)");
|
||||
{
|
||||
static std::vector<double> dates, opens, closes, lows, highs;
|
||||
if (dates.empty()) {
|
||||
dates.reserve(30); opens.reserve(30); closes.reserve(30);
|
||||
lows.reserve(30); highs.reserve(30);
|
||||
double price = 100.0;
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
double drift = std::sin(i * 0.4) * 1.2;
|
||||
double o = price;
|
||||
double c = price + drift + (i % 3 == 0 ? -0.6 : 0.4);
|
||||
double l = std::min(o, c) - 0.8 - (i % 5) * 0.1;
|
||||
double h = std::max(o, c) + 0.8 + (i % 4) * 0.1;
|
||||
dates.push_back(double(i));
|
||||
opens.push_back(o);
|
||||
closes.push_back(c);
|
||||
lows.push_back(l);
|
||||
highs.push_back(h);
|
||||
price = c;
|
||||
}
|
||||
}
|
||||
candlestick("##cs", dates.data(), opens.data(), closes.data(),
|
||||
lows.data(), highs.data(), int(dates.size()));
|
||||
}
|
||||
|
||||
code_block(
|
||||
"candlestick(\"##cs\", dates, opens, closes, lows, highs, n,\n"
|
||||
" /*width_percent=*/0.25f, /*tooltip=*/true);"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// gauge (Viz)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_gauge() {
|
||||
demo_header("gauge", "v1.0.0",
|
||||
"Indicador circular tipo velocimetro con ImGui DrawList. Color interpolado "
|
||||
"verde -> amarillo -> rojo segun el valor normalizado.");
|
||||
|
||||
static float v_cpu = 0.32f, v_mem = 0.78f, v_gpu = 0.55f;
|
||||
|
||||
section("Tres gauges con sliders");
|
||||
{
|
||||
ImGui::SliderFloat("cpu", &v_cpu, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("mem", &v_mem, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("gpu", &v_gpu, 0.0f, 1.0f);
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::BeginGroup();
|
||||
gauge("CPU", v_cpu, 0.0f, 1.0f, 60.0f);
|
||||
ImGui::EndGroup();
|
||||
ImGui::SameLine(0.0f, 24.0f);
|
||||
ImGui::BeginGroup();
|
||||
gauge("MEM", v_mem, 0.0f, 1.0f, 60.0f);
|
||||
ImGui::EndGroup();
|
||||
ImGui::SameLine(0.0f, 24.0f);
|
||||
ImGui::BeginGroup();
|
||||
gauge("GPU", v_gpu, 0.0f, 1.0f, 60.0f);
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
code_block("gauge(\"CPU\", 0.32f, 0.0f, 1.0f, 60.0f);");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// heatmap (Viz)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_heatmap() {
|
||||
demo_header("heatmap", "v1.0.0",
|
||||
"Mapa de calor 2D con ImPlot. Datos row-major. Util para correlation "
|
||||
"matrices, attention maps, distribuciones 2D discretas.");
|
||||
|
||||
constexpr int R = 12;
|
||||
constexpr int C = 12;
|
||||
static float values[R * C] = {0};
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
for (int r = 0; r < R; ++r) {
|
||||
for (int c = 0; c < C; ++c) {
|
||||
float dx = (c - C * 0.5f) / float(C);
|
||||
float dy = (r - R * 0.5f) / float(R);
|
||||
values[r * C + c] = std::exp(-(dx * dx + dy * dy) * 6.0f);
|
||||
}
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
section("Gaussian 12x12");
|
||||
{
|
||||
heatmap("##hm", values, R, C, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
code_block(
|
||||
"float values[R * C];\n"
|
||||
"// fill row-major: values[r * C + c] = ...\n"
|
||||
"heatmap(\"##hm\", values, R, C, /*min=*/0.0f, /*max=*/1.0f);"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// table_view (Viz)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void demo_table_view() {
|
||||
demo_header("table_view", "v1.0.0",
|
||||
"Tabla interactiva con sorting indicators y scroll usando la ImGui Tables API. "
|
||||
"Headers + cells row-major. Util para dashboards y inspectores.");
|
||||
|
||||
section("Lenguajes del registry");
|
||||
{
|
||||
const char* headers[] = {"id", "lang", "domain", "purity"};
|
||||
// 6 filas x 4 cols, row-major
|
||||
const char* cells[] = {
|
||||
"filter_slice_go_core", "go", "core", "pure",
|
||||
"metabase_setup_py_infra", "py", "infra", "impure",
|
||||
"rsync_deploy_bash_infra", "sh", "infra", "impure",
|
||||
"button_cpp_core", "cpp", "core", "pure",
|
||||
"gl_texture_load_cpp_gfx", "cpp", "gfx", "impure",
|
||||
"audio_fft_cpp_core", "cpp", "core", "pure",
|
||||
};
|
||||
const int row_count = 6;
|
||||
const int col_count = 4;
|
||||
table_view("##tbl", headers, col_count, cells, row_count);
|
||||
}
|
||||
|
||||
code_block(
|
||||
"const char* headers[] = {\"id\", \"lang\", \"domain\"};\n"
|
||||
"const char* cells[] = {/* row-major: r0c0,r0c1,r0c2, r1c0,... */};\n"
|
||||
"table_view(\"##tbl\", headers, 3, cells, n_rows);"
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gallery
|
||||
Reference in New Issue
Block a user