Files
Renderive/Core/plottable/Waterfall.cpp
T
2026-08-02 16:02:15 +08:00

162 lines
6.8 KiB
C++

#include <utility>
#include "../base/Memory.h"
#include "Waterfall_p.h"
namespace renderive {
RENDERIVE_DEFINE_RENDERABLE_BINDING(Waterfall, Waterfall_Private, Waterfall_Render_State, Waterfall_Input_Data, "Waterfall")
std::shared_ptr<Frequency_Axis> Waterfall::frequency_axis() {
return d()->edit_state_value(&Waterfall_Render_State::frequency_axis).lock();
}
void Waterfall::set_frequency_axis(std::shared_ptr<Frequency_Axis> value) {
d()->set_state_value(&Waterfall_Render_State::frequency_axis, std::weak_ptr<Frequency_Axis>(value));
}
std::shared_ptr<Time_Axis> Waterfall::time_axis() {
return d()->edit_state_value(&Waterfall_Render_State::time_axis).lock();
}
void Waterfall::set_time_axis(std::shared_ptr<Time_Axis> value) {
d()->set_state_value(&Waterfall_Render_State::time_axis, std::weak_ptr<Time_Axis>(value));
}
Range Waterfall::frequency_range() {
return d()->edit_state_value(&Waterfall_Render_State::frequency_range);
}
void Waterfall::set_frequency_range(Range value) {
if (value.length() == 0.0)
return;
d()->set_state_value(&Waterfall_Render_State::frequency_range, std::move(value));
}
Range Waterfall::power_range() {
return d()->edit_state_value(&Waterfall_Render_State::color_scale).range();
}
void Waterfall::set_power_range(Range value) {
if (value.size() == 0.0)
return;
Render_Edit_Lease<Waterfall_Private, Waterfall_Render_State> edit(d());
edit->color_scale.set_range(value);
}
int Waterfall::frequency_bin_count() {
return d()->edit_state_value(&Waterfall_Render_State::frequency_bin_count);
}
void Waterfall::set_frequency_bin_count(int value) {
d()->set_state_value(&Waterfall_Render_State::frequency_bin_count, std::max(1, value));
}
bool Waterfall::visible_range_only() {
return d()->edit_state_value(&Waterfall_Render_State::visible_range_only);
}
void Waterfall::set_visible_range_only(bool value) {
d()->set_state_value(&Waterfall_Render_State::visible_range_only, value);
}
Image_Interpolation_Mode Waterfall::interpolation_mode() {
return d()->edit_state_value(&Waterfall_Render_State::interpolation_mode);
}
void Waterfall::set_interpolation_mode(Image_Interpolation_Mode value) {
d()->set_state_value(&Waterfall_Render_State::interpolation_mode, value);
}
Waterfall_Row_Update_Policy Waterfall::row_update_policy() {
return d()->edit_state_value(&Waterfall_Render_State::row_update_policy);
}
void Waterfall::set_row_update_policy(Waterfall_Row_Update_Policy value) {
d()->set_state_value(&Waterfall_Render_State::row_update_policy, value);
}
int Waterfall::latest_row_min_interval_ms() {
return d()->edit_state_value(&Waterfall_Render_State::latest_row_min_interval_ms);
}
void Waterfall::set_latest_row_min_interval_ms(int value) {
d()->set_state_value(&Waterfall_Render_State::latest_row_min_interval_ms, std::max(1, value));
}
Color_Map Waterfall::color_map() {
return d()->edit_state_value(&Waterfall_Render_State::color_scale).color_map();
}
void Waterfall::set_color_map(Color_Map value) {
Render_Edit_Lease<Waterfall_Private, Waterfall_Render_State> edit(d());
edit->color_scale.set_color_map(std::move(value));
}
std::shared_ptr<Color_Bar> Waterfall::get_color_bar() const {
return const_cast<Waterfall*>(this)->d()->color_bar.lock();
}
void Waterfall::append_row(int tick, std::span<const double> data) {
if (!ok())
return;
d()->enqueue_row(tick, data);
}
void Waterfall::append_row(int tick, std::pmr::vector<double>&& data) {
if (!ok())
return;
d()->enqueue_row(tick, std::move(data));
}
void Waterfall::append_row(Time_Of_Day time, std::span<const double> data) {
if (!ok())
return;
auto axis = time_axis();
if (!axis)
return;
auto stream = axis->timeline_stream();
if (!stream)
return;
int tick = stream->append_time(time);
d()->enqueue_row(tick, data);
}
void Waterfall::append_row(Time_Of_Day time, std::pmr::vector<double>&& data) {
if (!ok())
return;
auto axis = time_axis();
if (!axis)
return;
auto stream = axis->timeline_stream();
if (!stream)
return;
int tick = stream->append_time(time);
d()->enqueue_row(tick, std::move(data));
}
Update_Ticket Waterfall::submit_data(int tick, std::span<const double> data) {
auto state = make_update_state();
if (!ok()) {
state->complete_all(std::make_error_code(std::errc::operation_canceled), Update_Outcome::Cancelled);
return Update_Ticket(state);
}
d()->enqueue_row(tick, data, state);
return Update_Ticket(state);
}
Update_Ticket Waterfall::submit_data(int tick, std::pmr::vector<double>&& data) {
auto state = make_update_state();
if (!ok()) {
state->complete_all(std::make_error_code(std::errc::operation_canceled), Update_Outcome::Cancelled);
return Update_Ticket(state);
}
d()->enqueue_row(tick, std::move(data), state);
return Update_Ticket(state);
}
Waterfall::Builder::Builder(std::shared_ptr<Renderable> parent, std::shared_ptr<Frequency_Axis> frequency_axis, std::shared_ptr<Time_Axis> time_axis) {
ASSERT(parent && parent->attached_to_plot(), "Waterfall build error! parent invalid");
ASSERT(frequency_axis && time_axis, "Waterfall build error! axis == nullptr");
ASSERT(frequency_axis->attached_to_plot(), "Waterfall build error! frequency_axis->plot == nullptr");
ASSERT(frequency_axis->shares_plot_with(*time_axis), "Waterfall build error! frequency_axis->plot != time_axis->plot");
ASSERT(parent->shares_plot_with(*frequency_axis), "Waterfall build error! parent->plot != frequency_axis->plot");
ASSERT(frequency_axis->orientation() != time_axis->orientation(), "Waterfall build error! axes must be orthogonal");
this->parent = parent;
this->frequency_axis = frequency_axis;
this->time_axis = time_axis;
}
std::shared_ptr<Waterfall> Waterfall::Builder::build() {
auto ret = renderive::make_shared<Waterfall>();
ret->init(parent);
Waterfall_Private* pd = ret->d();
Render_Edit_Lease<Waterfall_Private, Waterfall_Render_State> edit(pd);
Waterfall_Render_State* sc = edit.operator->();
PROP_R(std::weak_ptr<Frequency_Axis>, frequency_axis)
PROP_R(std::weak_ptr<Time_Axis>, time_axis)
PROP_R(Range, frequency_range)
PROP_R(int, frequency_bin_count)
PROP_R(bool, visible_range_only)
PROP_R(Image_Interpolation_Mode, interpolation_mode)
PROP_R(Waterfall_Row_Update_Policy, row_update_policy)
PROP_R(int, latest_row_min_interval_ms)
sc->color_scale = color_scale.clone();
sc->frequency_bin_count = std::max(1, sc->frequency_bin_count);
sc->latest_row_min_interval_ms = std::max(1, sc->latest_row_min_interval_ms);
if (color_bar_enabled) {
auto bar = Color_Bar::Builder(ret).set_color_scale(sc->color_scale).set_name("Waterfall").build();
pd->color_bar = bar;
}
return ret;
}
} // namespace renderive