162 lines
6.8 KiB
C++
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
|