Files
Aethera/render_2D/tests/Plottable_Migration_Test.cpp
2026-09-03 12:38:51 +08:00

122 lines
7.0 KiB
C++

#include <render_2D/module/plottable/Plottables.hpp>
#include <gtest/gtest.h>
#include <chrono>
namespace {
using namespace aethera;
using namespace aethera::render_2d;
template <typename Axis>
std::unique_ptr<Axis> make_axis(Axis_Orientation orientation, Axis_Range range) {
typename Axis::Builder builder;
builder
.set<Prop_Tag>(&Abs_Axis::Prop::position, Point_F{10.0, 90.0})
.set<Prop_Tag>(&Abs_Axis::Prop::pixel_length, orientation == Axis_Orientation::horizontal ? 100.0 : -80.0)
.set<Prop_Tag>(&Abs_Axis::Prop::orientation, orientation);
if constexpr (std::derived_from<Axis, Numeric_Axis>) builder.template set<Prop_Tag>(&Numeric_Axis::Prop::coordinate_range, range);
auto axis = builder.build();
aethera::detail::model_private(*axis).advance();
return axis;
}
TEST(Plottable_Migration, Frequency_Trace_And_Sweep_Use_Import_Lists) {
auto time = Time_Axis::Builder{}.build();
auto value = make_axis<Numeric_Axis>(Axis_Orientation::vertical, {0.0, 100.0});
time->set<Prop_Tag>(&Abs_Axis::Prop::position, Point_F{10.0, 90.0});
time->set<Prop_Tag>(&Abs_Axis::Prop::pixel_length, 100.0);
time->append_time({1'000});
time->append_time({2'000});
aethera::detail::model_private(*time).advance();
Frequency_Trace::Builder trace_builder(*time, *value);
auto trace = trace_builder.build();
trace->set<Frequency_Trace_Stream_Tag>([](Frequency_Trace::Samples& samples) { samples.push_back({0, 10.0}); samples.push_back({1, 80.0}); });
aethera::detail::model_private(*trace).advance();
Frequency_Trace::State trace_state;
trace->get<State_Tag>([&](const Frequency_Trace::State& state) { trace_state = state; });
EXPECT_EQ(trace_state.sample_count, 2U);
auto frequency = make_axis<Frequency_Axis>(Axis_Orientation::horizontal, {0.0, 100.0});
auto power = make_axis<Numeric_Axis>(Axis_Orientation::vertical, {-100.0, 0.0});
Sweep_Spectrum::Builder sweep_builder(*frequency, *power);
sweep_builder
.set<Prop_Tag>(&Sweep_Spectrum::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set<Prop_Tag>(&Sweep_Spectrum::Prop::block_count, 2U);
auto sweep = sweep_builder.build();
sweep->set<Sweep_Spectrum_Stream_Tag>([](Sweep_Spectrum::Blocks& blocks) { blocks.push_back(std::make_shared<const Sweep_Spectrum_Block>(Sweep_Spectrum_Block{0, {-90.0, -40.0}})); blocks.push_back(std::make_shared<const Sweep_Spectrum_Block>(Sweep_Spectrum_Block{1, {-30.0, -10.0}})); });
aethera::detail::model_private(*sweep).advance();
Sweep_Spectrum::State sweep_state;
sweep->get<State_Tag>([&](const Sweep_Spectrum::State& state) { sweep_state = state; });
EXPECT_EQ(sweep_state.stored_block_count, 2U);
}
TEST(Plottable_Migration, Raster_Plots_Keep_One_Private_History) {
auto frequency = make_axis<Frequency_Axis>(Axis_Orientation::horizontal, {0.0, 100.0});
auto power = make_axis<Numeric_Axis>(Axis_Orientation::vertical, {-100.0, 0.0});
Afterglow::Builder glow_builder(*frequency, *power);
glow_builder
.set<Prop_Tag>(&Afterglow::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set<Prop_Tag>(&Afterglow::Prop::power_range, Axis_Range{-100.0, 0.0})
.set<Prop_Tag>(&Afterglow::Prop::power_point_size, 16U)
.set<Prop_Tag>(&Afterglow::Prop::partition_grid, Plot_Partition_Grid{2, 2});
auto glow = glow_builder.build();
glow->set<Afterglow_Stream_Tag>([](Afterglow::Spectra& spectra) { spectra.push_back(std::make_shared<const std::vector<Plot_Value>>(std::vector<Plot_Value>{-90.0, -60.0, -30.0, -10.0})); });
aethera::detail::model_private(*glow).advance();
Afterglow::State glow_state;
glow->get<State_Tag>([&](const Afterglow::State& state) { glow_state = state; });
EXPECT_EQ(glow_state.spectrum_count, 1U);
auto time = Time_Axis::Builder{}.build();
time->set<Prop_Tag>(&Abs_Axis::Prop::position, Point_F{10.0, 90.0});
time->set<Prop_Tag>(&Abs_Axis::Prop::pixel_length, -80.0);
time->set<Prop_Tag>(&Abs_Axis::Prop::orientation, Axis_Orientation::vertical);
const auto first_tick = time->append_time({1'000});
const auto second_tick = time->append_time({2'000});
aethera::detail::model_private(*time).advance();
Waterfall::Builder waterfall_builder(*frequency, *time);
waterfall_builder
.set<Prop_Tag>(&Waterfall::Prop::frequency_range, Axis_Range{0.0, 100.0})
.set<Prop_Tag>(&Waterfall::Prop::power_range, Axis_Range{-100.0, 0.0})
.set<Prop_Tag>(&Waterfall::Prop::partition_grid, Plot_Partition_Grid{2, 2});
auto waterfall = waterfall_builder.build();
waterfall->set<Waterfall_Stream_Tag>([first_tick, second_tick](Waterfall::Rows& rows) { rows.push_back(std::make_shared<const Waterfall_Row>(Waterfall_Row{first_tick, {-90.0, -60.0, -30.0, -10.0}})); rows.push_back(std::make_shared<const Waterfall_Row>(Waterfall_Row{second_tick, {-80.0, -50.0, -20.0, -5.0}})); });
aethera::detail::model_private(*waterfall).advance();
Waterfall::State waterfall_state;
waterfall->get<State_Tag>([&](const Waterfall::State& state) { waterfall_state = state; });
EXPECT_EQ(waterfall_state.row_count, 2U);
}
TEST(Plottable_Migration, Constellation_And_Overlay_Use_Virtual_Private_Runtime) {
auto horizontal = make_axis<Numeric_Axis>(Axis_Orientation::horizontal, {-1.0, 1.0});
auto vertical = make_axis<Numeric_Axis>(Axis_Orientation::vertical, {-1.0, 1.0});
const auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
Constellation_Diagram::Builder diagram_builder(*horizontal, *vertical);
diagram_builder
.set<Prop_Tag>(&Constellation_Diagram::Prop::i_range, Axis_Range{-1.0, 1.0})
.set<Prop_Tag>(&Constellation_Diagram::Prop::q_range, Axis_Range{-1.0, 1.0});
auto diagram = diagram_builder.build();
diagram->set<Constellation_Stream_Tag>([now](Constellation_Diagram::Points& points) { points.push_back({{0.25, -0.25}, now}); });
aethera::detail::model_private(*diagram).advance();
Constellation_Diagram::State diagram_state;
diagram->get<State_Tag>([&](const Constellation_Diagram::State& state) { diagram_state = state; });
EXPECT_EQ(diagram_state.point_count, 1U);
Selection_Rectangle_Overlay::Builder overlay_builder(*horizontal, *vertical);
auto overlay = overlay_builder.build();
auto& overlay_private = aethera::detail::model_private(*overlay);
Pointer_Event press{Event_Type::pointer_press};
press.position = {20.0, 80.0};
press.button = Mouse_Button::left;
overlay_private.dispatch_event(press);
Pointer_Event move{Event_Type::pointer_move};
move.position = {60.0, 40.0};
overlay_private.dispatch_event(move);
Pointer_Event release{Event_Type::pointer_release};
release.position = move.position;
release.button = Mouse_Button::left;
overlay_private.dispatch_event(release);
overlay_private.advance();
std::size_t selected{};
overlay->get<Prop_Tag>([&](const Selection_Rectangle_Overlay::Prop& properties) { selected = properties.selected_regions.size(); });
EXPECT_EQ(selected, 1U);
}
} // namespace