加上实时数据和历史数据目标到私有类里
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "Sweep_Spectrum.h"
|
||||
#include "Curve_Sampling.h"
|
||||
#include "Plottable_Real_Time_Data.h"
|
||||
#include "../render/Blend2D_Cache.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
@@ -7,11 +8,7 @@
|
||||
namespace renderive {
|
||||
namespace detail {
|
||||
namespace {
|
||||
struct Sweep_Spectrum_Runtime_Base {};
|
||||
struct Sweep_Spectrum_Runtime {
|
||||
std::deque<std::vector<double>> blocks;
|
||||
};
|
||||
using Sweep_Spectrum_Runtime_State = Double_State_Strategy<Sweep_Spectrum_Runtime_Base, Sweep_Spectrum_Runtime>;
|
||||
using Sweep_Spectrum_History = Plottable_History_Real_Time_Data<std::vector<double>, std::deque<std::vector<double>>>;
|
||||
RectF axis_content_rect(const Axis_Transform& horizontal, const Axis_Transform& vertical) {
|
||||
const double x1 = horizontal.coord_to_pixel(horizontal.coordinate_range.origin);
|
||||
const double x2 = horizontal.coord_to_pixel(horizontal.coordinate_range.target);
|
||||
@@ -19,72 +16,63 @@ RectF axis_content_rect(const Axis_Transform& horizontal, const Axis_Transform&
|
||||
const double y2 = vertical.coord_to_pixel(vertical.coordinate_range.target);
|
||||
return {std::min(x1, x2), std::min(y1, y2), std::abs(x2 - x1), std::abs(y2 - y1)};
|
||||
}
|
||||
std::vector<double> flatten(const Sweep_Spectrum_Runtime& runtime) {
|
||||
std::vector<double> flatten(const std::deque<std::vector<double>>& blocks) {
|
||||
std::vector<double> values;
|
||||
for(const auto& block : runtime.blocks)
|
||||
for(const auto& block : blocks)
|
||||
values.insert(values.end(), block.begin(), block.end());
|
||||
return values;
|
||||
}
|
||||
}
|
||||
struct Sweep_Spectrum_Control::Impl {
|
||||
Impl(std::shared_ptr<Axis> frequency, std::shared_ptr<Axis> power) : frequency_axis(std::move(frequency)), power_axis(std::move(power)) {}
|
||||
Impl(Sweep_Spectrum_Control& owner, std::shared_ptr<Axis> frequency, std::shared_ptr<Axis> power)
|
||||
: frequency_axis(std::move(frequency)), power_axis(std::move(power)), blocks(observe_real_time_data(owner)) {}
|
||||
std::shared_ptr<Axis> frequency_axis;
|
||||
std::shared_ptr<Axis> power_axis;
|
||||
Sweep_Spectrum_Runtime_State runtime;
|
||||
Sweep_Spectrum_History blocks;
|
||||
};
|
||||
Sweep_Spectrum_Control::Sweep_Spectrum_Control(Plot_Core& plot, const Sweep_Spectrum_Properties& properties, std::shared_ptr<Axis> frequency_axis, std::shared_ptr<Axis> power_axis)
|
||||
: Plottable_State(plot, properties), impl_(std::make_unique<Impl>(std::move(frequency_axis), std::move(power_axis))) {}
|
||||
: Plottable_State(plot, properties), impl_(std::make_unique<Impl>(*this, std::move(frequency_axis), std::move(power_axis))) {}
|
||||
Sweep_Spectrum_Control::~Sweep_Spectrum_Control() = default;
|
||||
void Sweep_Spectrum_Control::append_block(std::span<const double> values) {
|
||||
if(get<&Sweep_Spectrum_Properties::bins_per_block>() <= 0)
|
||||
set<&Sweep_Spectrum_Properties::bins_per_block>(static_cast<int>(values.size()));
|
||||
const int limit = get<&Sweep_Spectrum_Properties::block_count>();
|
||||
impl_->runtime.update([values, limit](Sweep_Spectrum_Runtime& runtime) {
|
||||
runtime.blocks.emplace_back(values.begin(), values.end());
|
||||
while(runtime.blocks.size() > static_cast<std::size_t>(limit))
|
||||
runtime.blocks.pop_front();
|
||||
});
|
||||
impl_->blocks.update({values.begin(), values.end()}, static_cast<std::size_t>(limit));
|
||||
changed();
|
||||
}
|
||||
void Sweep_Spectrum_Control::append_block(std::pmr::vector<double>&& values) {
|
||||
append_block(std::span<const double>(values.data(), values.size()));
|
||||
}
|
||||
std::size_t Sweep_Spectrum_Control::stored_block_count() const {
|
||||
return impl_->runtime.read([](const Sweep_Spectrum_Runtime& runtime) { return runtime.blocks.size(); });
|
||||
return impl_->blocks.size();
|
||||
}
|
||||
std::size_t Sweep_Spectrum_Control::stored_point_count() const {
|
||||
return impl_->runtime.read([](const Sweep_Spectrum_Runtime& runtime) {
|
||||
std::size_t count{};
|
||||
for(const auto& block : runtime.blocks)
|
||||
count += block.size();
|
||||
return count;
|
||||
});
|
||||
const auto blocks = impl_->blocks.snapshot();
|
||||
std::size_t count{};
|
||||
for(const auto& block : blocks)
|
||||
count += block.size();
|
||||
return count;
|
||||
}
|
||||
std::size_t Sweep_Spectrum_Control::rendered_point_count() const {
|
||||
const auto state = properties();
|
||||
const auto runtime = impl_->runtime.read([](const Sweep_Spectrum_Runtime& value) { return value; });
|
||||
const auto values = flatten(runtime);
|
||||
const auto values = flatten(impl_->blocks.snapshot());
|
||||
return curve_points(values, state.frequency_range, impl_->frequency_axis->transform(), impl_->power_axis->transform(), state.visible_range_only, state.interpolation_mode).size();
|
||||
}
|
||||
void Sweep_Spectrum_Control::publish() {
|
||||
publish_properties();
|
||||
const int limit = get<&Sweep_Spectrum_Properties::block_count>();
|
||||
impl_->runtime.update([limit](Sweep_Spectrum_Runtime& runtime) {
|
||||
while(runtime.blocks.size() > static_cast<std::size_t>(limit))
|
||||
runtime.blocks.pop_front();
|
||||
});
|
||||
impl_->runtime.publish();
|
||||
impl_->blocks.retain_latest(static_cast<std::size_t>(limit));
|
||||
}
|
||||
void Sweep_Spectrum_Control::paint(Painter& painter) {
|
||||
const auto state = render_properties();
|
||||
const auto runtime = impl_->runtime.render_use_state();
|
||||
const auto values = flatten(runtime);
|
||||
const auto blocks = impl_->blocks.snapshot();
|
||||
const auto values = flatten(blocks);
|
||||
if(values.size() < 2)
|
||||
return;
|
||||
const Axis_Transform x = impl_->frequency_axis->transform();
|
||||
const Axis_Transform y = impl_->power_axis->transform();
|
||||
painter.polyline(curve_points(values, state.frequency_range, x, y, state.visible_range_only, state.interpolation_mode), state.pen);
|
||||
const double completed = std::min(1.0, static_cast<double>(runtime.blocks.size()) / state.block_count.get());
|
||||
const double completed = std::min(1.0, static_cast<double>(blocks.size()) / state.block_count.get());
|
||||
const double frequency = state.frequency_range.origin + state.frequency_range.length() * completed;
|
||||
const RectF content = axis_content_rect(x, y);
|
||||
const double marker_x = x.coord_to_pixel(frequency);
|
||||
|
||||
Reference in New Issue
Block a user