122 lines
7.0 KiB
C++
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
|