引入asio
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
#include "Gallery_Scene2D.h"
|
||||
|
||||
#include "../Gallery_Capture_Json.h"
|
||||
#include "../common/Observer_Json.h"
|
||||
#include "../Pixel_Frame.h"
|
||||
@@ -14,7 +13,6 @@
|
||||
#include "render_2D/plottable/Sweep_Spectrum.h"
|
||||
#include "render_2D/plottable/Waterfall.h"
|
||||
#include "render_2D/scene/Render_Scene_2D.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
@@ -24,7 +22,7 @@
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <asio.hpp>
|
||||
namespace renderive::web {
|
||||
template <>
|
||||
struct Observer_Pfr_Adapter<Render_Scene_2D::State> {
|
||||
@@ -42,16 +40,12 @@ constexpr std::size_t sweep_block_count = 8;
|
||||
std::shared_ptr<Frame_Control_Strategy_Base> make_strategy(
|
||||
Gallery_Frame_Mode mode) {
|
||||
switch (mode) {
|
||||
case Gallery_Frame_Mode::Manual:
|
||||
return std::make_shared<Manual_Render_Scene_2D_Strategy>();
|
||||
case Gallery_Frame_Mode::Low_Latency:
|
||||
return std::make_shared<Low_Latency_Render_Scene_2D_Strategy>();
|
||||
case Gallery_Frame_Mode::Playback:
|
||||
return std::make_shared<Playback_Render_Scene_2D_Strategy>();
|
||||
case Gallery_Frame_Mode::Manual: return std::make_shared<Manual_Render_Scene_2D_Strategy>();
|
||||
case Gallery_Frame_Mode::Low_Latency: return std::make_shared<Low_Latency_Render_Scene_2D_Strategy>();
|
||||
case Gallery_Frame_Mode::Playback: return std::make_shared<Playback_Render_Scene_2D_Strategy>();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string_view mode_id(Gallery_Frame_Mode mode) {
|
||||
switch (mode) {
|
||||
case Gallery_Frame_Mode::Manual: return "manual";
|
||||
@@ -60,56 +54,54 @@ std::string_view mode_id(Gallery_Frame_Mode mode) {
|
||||
}
|
||||
return "low_latency";
|
||||
}
|
||||
|
||||
Gallery_Frame_Mode strategy_mode(const Frame_Control_Strategy_Base& strategy) {
|
||||
if (dynamic_cast<const Manual_Render_Scene_2D_Strategy*>(&strategy))
|
||||
return Gallery_Frame_Mode::Manual;
|
||||
if (dynamic_cast<const Playback_Render_Scene_2D_Strategy*>(&strategy))
|
||||
return Gallery_Frame_Mode::Playback;
|
||||
if (dynamic_cast<const Manual_Render_Scene_2D_Strategy*>(&strategy)) return Gallery_Frame_Mode::Manual;
|
||||
if (dynamic_cast<const Playback_Render_Scene_2D_Strategy*>(&strategy)) return Gallery_Frame_Mode::Playback;
|
||||
return Gallery_Frame_Mode::Low_Latency;
|
||||
}
|
||||
|
||||
Time_Of_Day current_time_of_day() {
|
||||
constexpr std::int64_t day_ms = 24LL * 60LL * 60LL * 1000LL;
|
||||
const auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count();
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count();
|
||||
return {now % day_ms};
|
||||
}
|
||||
|
||||
class Gallery_Scene2D final : public Gallery_Scene_Interface {
|
||||
public:
|
||||
Gallery_Scene2D(std::string case_id, Gallery_Frame_Mode mode)
|
||||
: case_id_(std::move(case_id)) {
|
||||
Gallery_Scene2D(std::string case_id, Gallery_Frame_Mode mode) : case_id_(std::move(case_id)) {
|
||||
rebuild(mode);
|
||||
}
|
||||
|
||||
~Gallery_Scene2D() override {
|
||||
if (scene_) scene_->deactivate_view();
|
||||
}
|
||||
|
||||
const std::string& case_id() const noexcept override { return case_id_; }
|
||||
|
||||
nlohmann::json controls() const override {
|
||||
return {{"resources", nlohmann::json::array()},
|
||||
{"observers", nlohmann::json::array()},
|
||||
{"render_plan", gallery_render_plan_json(*scene_)},
|
||||
{"performance_capture",
|
||||
gallery_performance_capture_json(*scene_)}};
|
||||
const std::string& case_id() const noexcept override {
|
||||
return case_id_;
|
||||
}
|
||||
nlohmann::json controls() const override {
|
||||
return {
|
||||
{"resources", nlohmann::json::array()},
|
||||
{"observers", nlohmann::json::array()},
|
||||
{"render_plan", gallery_render_plan_json(*scene_)},
|
||||
{
|
||||
"performance_capture",
|
||||
gallery_performance_capture_json(*scene_)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Gallery_Frame_Mode frame_mode() const noexcept override {
|
||||
return strategy_mode(*scene_->frame_control_strategy());
|
||||
}
|
||||
void reset_monitoring() override { render_count_ = 0; }
|
||||
|
||||
void reset_monitoring() override {
|
||||
render_count_ = 0;
|
||||
}
|
||||
void set_client_metrics(Gallery_Client_Performance metrics) noexcept override {
|
||||
client_ = metrics;
|
||||
constexpr double maximum_interval_ms =
|
||||
static_cast<double>(std::numeric_limits<std::uint64_t>::max()) /
|
||||
1'000'000.0;
|
||||
static_cast<double>(std::numeric_limits<std::uint64_t>::max()) /
|
||||
1'000'000.0;
|
||||
if (metrics.display_interval_latest_ms <= 0.0 ||
|
||||
metrics.display_interval_latest_ms > maximum_interval_ms) return;
|
||||
metrics.display_interval_latest_ms > maximum_interval_ms)
|
||||
return;
|
||||
const auto observed_interval_ns = static_cast<std::uint64_t>(
|
||||
metrics.display_interval_latest_ms * 1'000'000.0);
|
||||
if (observed_interval_ns == 0) return;
|
||||
@@ -120,12 +112,10 @@ public:
|
||||
Frame_Consumer_Feedback{observed_interval_ns}));
|
||||
}
|
||||
}
|
||||
|
||||
adminive::Update_Result apply_patch(
|
||||
std::string_view, const nlohmann::json&) override {
|
||||
return {false, "no editable resource matches the requested target"};
|
||||
}
|
||||
|
||||
void resize(int width, int height) override {
|
||||
const Size requested{std::max(1, width), std::max(1, height)};
|
||||
if (requested == viewport_) return;
|
||||
@@ -133,30 +123,23 @@ public:
|
||||
viewport_ = requested;
|
||||
rebuild(mode);
|
||||
}
|
||||
|
||||
void dispatch(const Gallery_Input_Event& event) override {
|
||||
std::visit([this](const auto& value) {
|
||||
using T = std::decay_t<decltype(value)>;
|
||||
if constexpr (std::same_as<T, Gallery_View_Input>) {
|
||||
if (value.type == Gallery_View_Input_Type::Show)
|
||||
scene_->activate_view();
|
||||
else if (value.type == Gallery_View_Input_Type::Hide)
|
||||
scene_->deactivate_view();
|
||||
if (value.type == Gallery_View_Input_Type::Show) scene_->activate_view();
|
||||
else if (value.type == Gallery_View_Input_Type::Hide) scene_->deactivate_view();
|
||||
}
|
||||
}, event);
|
||||
}
|
||||
|
||||
bool request_frame() override {
|
||||
update_samples();
|
||||
const auto result = scene_->render_frame();
|
||||
if (!result || *result != Plot_Render_Status::rendered)
|
||||
return false;
|
||||
if (scene_->wait_for_render() != Scene_Render_Result::none)
|
||||
return false;
|
||||
if (!result || *result != Plot_Render_Status::rendered) return false;
|
||||
if (scene_->wait_for_render() != Scene_Render_Result::none) return false;
|
||||
++render_count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<std::string> encode_latest_pixels() override {
|
||||
std::string result;
|
||||
scene_->with_frame([&](Image_View image) {
|
||||
@@ -165,12 +148,10 @@ public:
|
||||
if (result.empty()) return std::nullopt;
|
||||
return result;
|
||||
}
|
||||
|
||||
void record_pixel_response(std::chrono::steady_clock::time_point,
|
||||
std::chrono::steady_clock::time_point,
|
||||
std::chrono::steady_clock::time_point,
|
||||
std::size_t) override {}
|
||||
|
||||
std::string action(const Gallery_Action_Request& request,
|
||||
bool& recognized) override {
|
||||
recognized = true;
|
||||
@@ -179,16 +160,15 @@ public:
|
||||
request.id == "frame_strategy_playback") {
|
||||
const auto next = request.id == "frame_strategy_manual"
|
||||
? Gallery_Frame_Mode::Manual
|
||||
: request.id == "frame_strategy_playback"
|
||||
? Gallery_Frame_Mode::Playback
|
||||
: Gallery_Frame_Mode::Low_Latency;
|
||||
: request.id == "frame_strategy_playback"
|
||||
? Gallery_Frame_Mode::Playback
|
||||
: Gallery_Frame_Mode::Low_Latency;
|
||||
const auto operation = scene_->edit_renderables(
|
||||
[strategy = make_strategy(next)](
|
||||
Scene_2D_Base::Renderable_Editor& editor) mutable {
|
||||
editor.replace_frame_control_strategy(std::move(strategy));
|
||||
});
|
||||
if (operation.wait() != Scene_Edit_Error::none)
|
||||
return "frame strategy replacement rejected";
|
||||
if (operation.wait() != Scene_Edit_Error::none) return "frame strategy replacement rejected";
|
||||
return "frame strategy replaced";
|
||||
}
|
||||
if (request.id == "capture_next_frame") {
|
||||
@@ -206,9 +186,7 @@ public:
|
||||
recognized = false;
|
||||
return {};
|
||||
}
|
||||
|
||||
void record_action_notice_if_empty(std::string_view) override {}
|
||||
|
||||
std::string telemetry_json() const override {
|
||||
const auto observer = scene_->observer();
|
||||
auto kernel_observer = observer_json(observer);
|
||||
@@ -219,180 +197,182 @@ public:
|
||||
{"kernel_observer", std::move(kernel_observer)},
|
||||
{"performance", {{"successful_render_count", render_count_}}},
|
||||
{"client_performance", {{"transport_fps", client_.transport_fps}}},
|
||||
{"performance_capture", gallery_performance_capture_json(*scene_)}}
|
||||
.dump();
|
||||
{"performance_capture", gallery_performance_capture_json(*scene_)}
|
||||
}
|
||||
.dump();
|
||||
}
|
||||
|
||||
private:
|
||||
template <class Product, class... Arguments>
|
||||
static renderive_Owner<Product> build(
|
||||
typename Product::Builder& builder, Arguments&&... arguments) {
|
||||
return static_cast<Renderable_Builder<Product, typename Product::State>&>(
|
||||
builder)
|
||||
.build(std::forward<Arguments>(arguments)...);
|
||||
builder)
|
||||
.build(std::forward<Arguments>(arguments)...);
|
||||
}
|
||||
|
||||
void rebuild(Gallery_Frame_Mode mode) {
|
||||
Render_Scene_2D::State scene_state;
|
||||
scene_state.viewport = viewport_;
|
||||
scene_state.background = Color{3, 8, 14, 255};
|
||||
scene_ = Render_Scene_2D::Builder{scene_state}.build(
|
||||
make_strategy(mode));
|
||||
|
||||
{
|
||||
auto attach = scene_->attach_builder();
|
||||
const auto root = scene_->root_renderable();
|
||||
|
||||
const bool numeric_domain =
|
||||
auto attach = scene_->attach_builder();
|
||||
const auto root = scene_->root_renderable();
|
||||
const bool numeric_domain =
|
||||
case_id_ == "sweep_spectrum" || case_id_ == "constellation";
|
||||
const bool time_domain = case_id_ == "frequency_trace";
|
||||
const int left = 62;
|
||||
const int top = 18;
|
||||
const auto width = static_cast<std::size_t>(
|
||||
std::max(1, viewport_.width - 86));
|
||||
const auto height = static_cast<std::size_t>(
|
||||
std::max(1, viewport_.height - 64));
|
||||
if (time_domain || case_id_ == "waterfall" || case_id_ == "axis_lab") {
|
||||
Time_Axis::State state;
|
||||
state.orientation = time_domain || case_id_ == "axis_lab"
|
||||
? Orientation::Horizontal
|
||||
: Orientation::Vertical;
|
||||
state.visible_count = 80;
|
||||
state.x = left;
|
||||
state.y = state.orientation == Orientation::Horizontal
|
||||
? top + static_cast<int>(height)
|
||||
: top;
|
||||
state.pixel_length =
|
||||
const bool time_domain = case_id_ == "frequency_trace";
|
||||
const int left = 62;
|
||||
const int top = 18;
|
||||
const auto width = static_cast<std::size_t>(
|
||||
std::max(1, viewport_.width - 86));
|
||||
const auto height = static_cast<std::size_t>(
|
||||
std::max(1, viewport_.height - 64));
|
||||
if (time_domain || case_id_ == "waterfall" || case_id_ == "axis_lab") {
|
||||
Time_Axis::State state;
|
||||
state.orientation = time_domain || case_id_ == "axis_lab"
|
||||
? Orientation::Horizontal
|
||||
: Orientation::Vertical;
|
||||
state.visible_count = 80;
|
||||
state.x = left;
|
||||
state.y = state.orientation == Orientation::Horizontal
|
||||
? top + static_cast<int>(height)
|
||||
: top;
|
||||
state.pixel_length =
|
||||
state.orientation == Orientation::Horizontal ? width : height;
|
||||
state.color = Color{69, 221, 190, 255};
|
||||
Time_Axis::Builder builder{state, &attach};
|
||||
time_axis_ = build<Time_Axis>(builder, root);
|
||||
time_axis_->set_object_name("Time Axis");
|
||||
}
|
||||
if (!time_domain && !numeric_domain) {
|
||||
Frequency_Axis::State state;
|
||||
state.orientation = Orientation::Horizontal;
|
||||
state.coordinates = Range{88'000'000.0, 108'000'000.0};
|
||||
state.x = left;
|
||||
state.y = top + static_cast<int>(height);
|
||||
state.pixel_length = width;
|
||||
state.color = Color{118, 145, 184, 255};
|
||||
state.wheel = true;
|
||||
state.drag = true;
|
||||
Frequency_Axis::Builder builder{state, &attach};
|
||||
frequency_axis_ = build<Frequency_Axis>(builder, root);
|
||||
frequency_axis_->set_object_name("Frequency Axis");
|
||||
} else if (numeric_domain) {
|
||||
Axis::State state;
|
||||
state.orientation = Orientation::Horizontal;
|
||||
state.coordinates = case_id_ == "constellation"
|
||||
? Range{-1.25, 1.25}
|
||||
: Range{0.0, 300.0};
|
||||
state.x = left;
|
||||
state.y = top + static_cast<int>(height);
|
||||
state.pixel_length = width;
|
||||
state.color = Color{118, 145, 184, 255};
|
||||
state.wheel = true;
|
||||
state.drag = true;
|
||||
Axis::Builder builder{state, &attach};
|
||||
domain_axis_ = build<Axis>(builder, root);
|
||||
domain_axis_->set_object_name("Domain Axis");
|
||||
}
|
||||
if (case_id_ != "waterfall") {
|
||||
Axis::State state;
|
||||
state.orientation = Orientation::Vertical;
|
||||
state.coordinates = case_id_ == "constellation"
|
||||
? Range{-1.25, 1.25}
|
||||
: time_domain ? Range{-1.0, 1.0}
|
||||
: Range{-120.0, -20.0};
|
||||
state.x = left;
|
||||
state.y = top;
|
||||
state.pixel_length = height;
|
||||
state.color = Color{118, 145, 184, 255};
|
||||
Axis::Builder builder{state, &attach};
|
||||
value_axis_ = build<Axis>(builder, root);
|
||||
value_axis_->set_object_name("Value Axis");
|
||||
}
|
||||
if (case_id_ == "spectrum" || case_id_ == "selection_overlay") {
|
||||
Spectrum::State state;
|
||||
state.frequency_range = {88'000'000.0, 108'000'000.0};
|
||||
state.frequency_point_size = 512;
|
||||
state.center_frequency = 98'000'000.0;
|
||||
state.max_hold_visible = true;
|
||||
state.current_pen = {Color{53, 230, 178, 255}, 2.0};
|
||||
state.max_pen = {Color{255, 209, 102, 255}, 1.2};
|
||||
state.min_pen = {Color{122, 162, 255, 255}, 1.2};
|
||||
Spectrum::Builder builder{state, &attach};
|
||||
spectrum_ = build<Spectrum>(
|
||||
builder, root, frequency_axis_, value_axis_);
|
||||
spectrum_->set_object_name("Spectrum");
|
||||
if (case_id_ == "selection_overlay") {
|
||||
Selection_Rectangle_Overlay::State overlay_state;
|
||||
overlay_state.selection_brush =
|
||||
{Color{23, 59, 102, 90}, Brush_Style::Solid};
|
||||
Selection_Rectangle_Overlay::Builder overlay_builder{
|
||||
overlay_state, &attach};
|
||||
selection_ = build<Selection_Rectangle_Overlay>(
|
||||
overlay_builder, root, frequency_axis_, value_axis_);
|
||||
selection_->set_object_name("Selection Overlay");
|
||||
state.color = Color{69, 221, 190, 255};
|
||||
Time_Axis::Builder builder{state, &attach};
|
||||
time_axis_ = build<Time_Axis>(builder, root);
|
||||
time_axis_->set_object_name("Time Axis");
|
||||
}
|
||||
if (!time_domain && !numeric_domain) {
|
||||
Frequency_Axis::State state;
|
||||
state.orientation = Orientation::Horizontal;
|
||||
state.coordinates = Range{88'000'000.0, 108'000'000.0};
|
||||
state.x = left;
|
||||
state.y = top + static_cast<int>(height);
|
||||
state.pixel_length = width;
|
||||
state.color = Color{118, 145, 184, 255};
|
||||
state.wheel = true;
|
||||
state.drag = true;
|
||||
Frequency_Axis::Builder builder{state, &attach};
|
||||
frequency_axis_ = build<Frequency_Axis>(builder, root);
|
||||
frequency_axis_->set_object_name("Frequency Axis");
|
||||
}
|
||||
else if (numeric_domain) {
|
||||
Axis::State state;
|
||||
state.orientation = Orientation::Horizontal;
|
||||
state.coordinates = case_id_ == "constellation"
|
||||
? Range{-1.25, 1.25}
|
||||
: Range{0.0, 300.0};
|
||||
state.x = left;
|
||||
state.y = top + static_cast<int>(height);
|
||||
state.pixel_length = width;
|
||||
state.color = Color{118, 145, 184, 255};
|
||||
state.wheel = true;
|
||||
state.drag = true;
|
||||
Axis::Builder builder{state, &attach};
|
||||
domain_axis_ = build<Axis>(builder, root);
|
||||
domain_axis_->set_object_name("Domain Axis");
|
||||
}
|
||||
if (case_id_ != "waterfall") {
|
||||
Axis::State state;
|
||||
state.orientation = Orientation::Vertical;
|
||||
state.coordinates = case_id_ == "constellation"
|
||||
? Range{-1.25, 1.25}
|
||||
: time_domain
|
||||
? Range{-1.0, 1.0}
|
||||
: Range{-120.0, -20.0};
|
||||
state.x = left;
|
||||
state.y = top;
|
||||
state.pixel_length = height;
|
||||
state.color = Color{118, 145, 184, 255};
|
||||
Axis::Builder builder{state, &attach};
|
||||
value_axis_ = build<Axis>(builder, root);
|
||||
value_axis_->set_object_name("Value Axis");
|
||||
}
|
||||
if (case_id_ == "spectrum" || case_id_ == "selection_overlay") {
|
||||
Spectrum::State state;
|
||||
state.frequency_range = {88'000'000.0, 108'000'000.0};
|
||||
state.frequency_point_size = 512;
|
||||
state.center_frequency = 98'000'000.0;
|
||||
state.max_hold_visible = true;
|
||||
state.current_pen = {Color{53, 230, 178, 255}, 2.0};
|
||||
state.max_pen = {Color{255, 209, 102, 255}, 1.2};
|
||||
state.min_pen = {Color{122, 162, 255, 255}, 1.2};
|
||||
Spectrum::Builder builder{state, &attach};
|
||||
spectrum_ = build<Spectrum>(
|
||||
builder, root, frequency_axis_, value_axis_);
|
||||
spectrum_->set_object_name("Spectrum");
|
||||
if (case_id_ == "selection_overlay") {
|
||||
Selection_Rectangle_Overlay::State overlay_state;
|
||||
overlay_state.selection_brush =
|
||||
{Color{23, 59, 102, 90}, Brush_Style::Solid};
|
||||
Selection_Rectangle_Overlay::Builder overlay_builder{
|
||||
overlay_state, &attach
|
||||
};
|
||||
selection_ = build<Selection_Rectangle_Overlay>(
|
||||
overlay_builder, root, frequency_axis_, value_axis_);
|
||||
selection_->set_object_name("Selection Overlay");
|
||||
}
|
||||
}
|
||||
else if (case_id_ == "waterfall") {
|
||||
Waterfall::State state;
|
||||
state.frequency_range = {88'000'000.0, 108'000'000.0};
|
||||
state.power_range = {-120.0, -20.0};
|
||||
state.frequency_bin_count = 256;
|
||||
Waterfall::Builder builder{state, &attach};
|
||||
waterfall_ = build<Waterfall>(
|
||||
builder, root, frequency_axis_, time_axis_);
|
||||
waterfall_->set_object_name("Waterfall");
|
||||
}
|
||||
else if (case_id_ == "afterglow") {
|
||||
Afterglow::State state;
|
||||
state.frequency_range = {88'000'000.0, 108'000'000.0};
|
||||
state.power_range = {-120.0, -20.0};
|
||||
state.frequency_point_size = 192;
|
||||
state.power_point_size = 96;
|
||||
state.attenuation_rate = 0.18;
|
||||
Afterglow::Builder builder{state, &attach};
|
||||
afterglow_ = build<Afterglow>(
|
||||
builder, root, frequency_axis_, value_axis_);
|
||||
// Afterglow::Builder(frequency_axis_, value_axis_).set_paint_rely({root}).set_render_rely({root}).build();
|
||||
afterglow_->set_object_name("Afterglow");
|
||||
}
|
||||
else if (case_id_ == "sweep_spectrum") {
|
||||
Sweep_Spectrum::State state;
|
||||
state.frequency_range = {0.0, 300.0};
|
||||
state.bins_per_block = static_cast<int>(sweep_bins_per_block);
|
||||
state.block_count = static_cast<int>(sweep_block_count);
|
||||
Sweep_Spectrum::Builder builder{state, &attach};
|
||||
sweep_ = build<Sweep_Spectrum>(
|
||||
builder, root, domain_axis_, value_axis_);
|
||||
sweep_->set_object_name("Sweep Spectrum");
|
||||
}
|
||||
else if (case_id_ == "frequency_trace") {
|
||||
Frequency_Trace::State state;
|
||||
state.pen = {Color{53, 230, 178, 255}, 2.0};
|
||||
Frequency_Trace::Builder builder{state, &attach};
|
||||
trace_ = build<Frequency_Trace>(
|
||||
builder, root, time_axis_, value_axis_);
|
||||
trace_->set_object_name("Frequency Trace");
|
||||
}
|
||||
else if (case_id_ == "constellation") {
|
||||
Constellation_Diagram::State state;
|
||||
state.i_range = {-1.25, 1.25};
|
||||
state.q_range = {-1.25, 1.25};
|
||||
state.point_color = Color{73, 230, 195, 255};
|
||||
state.anchor_color = Color{255, 209, 102, 255};
|
||||
Constellation_Diagram::Builder builder{state, &attach};
|
||||
constellation_ = build<Constellation_Diagram>(
|
||||
builder, root, domain_axis_, value_axis_);
|
||||
constellation_->set_object_name("Constellation Diagram");
|
||||
}
|
||||
} else if (case_id_ == "waterfall") {
|
||||
Waterfall::State state;
|
||||
state.frequency_range = {88'000'000.0, 108'000'000.0};
|
||||
state.power_range = {-120.0, -20.0};
|
||||
state.frequency_bin_count = 256;
|
||||
Waterfall::Builder builder{state, &attach};
|
||||
waterfall_ = build<Waterfall>(
|
||||
builder, root, frequency_axis_, time_axis_);
|
||||
waterfall_->set_object_name("Waterfall");
|
||||
} else if (case_id_ == "afterglow") {
|
||||
Afterglow::State state;
|
||||
state.frequency_range = {88'000'000.0, 108'000'000.0};
|
||||
state.power_range = {-120.0, -20.0};
|
||||
state.frequency_point_size = 192;
|
||||
state.power_point_size = 96;
|
||||
state.attenuation_rate = 0.18;
|
||||
Afterglow::Builder builder{state, &attach};
|
||||
afterglow_ = build<Afterglow>(
|
||||
builder, root, frequency_axis_, value_axis_);
|
||||
afterglow_->set_object_name("Afterglow");
|
||||
} else if (case_id_ == "sweep_spectrum") {
|
||||
Sweep_Spectrum::State state;
|
||||
state.frequency_range = {0.0, 300.0};
|
||||
state.bins_per_block = static_cast<int>(sweep_bins_per_block);
|
||||
state.block_count = static_cast<int>(sweep_block_count);
|
||||
Sweep_Spectrum::Builder builder{state, &attach};
|
||||
sweep_ = build<Sweep_Spectrum>(
|
||||
builder, root, domain_axis_, value_axis_);
|
||||
sweep_->set_object_name("Sweep Spectrum");
|
||||
} else if (case_id_ == "frequency_trace") {
|
||||
Frequency_Trace::State state;
|
||||
state.pen = {Color{53, 230, 178, 255}, 2.0};
|
||||
Frequency_Trace::Builder builder{state, &attach};
|
||||
trace_ = build<Frequency_Trace>(
|
||||
builder, root, time_axis_, value_axis_);
|
||||
trace_->set_object_name("Frequency Trace");
|
||||
} else if (case_id_ == "constellation") {
|
||||
Constellation_Diagram::State state;
|
||||
state.i_range = {-1.25, 1.25};
|
||||
state.q_range = {-1.25, 1.25};
|
||||
state.point_color = Color{73, 230, 195, 255};
|
||||
state.anchor_color = Color{255, 209, 102, 255};
|
||||
Constellation_Diagram::Builder builder{state, &attach};
|
||||
constellation_ = build<Constellation_Diagram>(
|
||||
builder, root, domain_axis_, value_axis_);
|
||||
constellation_->set_object_name("Constellation Diagram");
|
||||
}
|
||||
}
|
||||
|
||||
scene_->activate_view();
|
||||
}
|
||||
|
||||
void update_samples() {
|
||||
const std::size_t count =
|
||||
waterfall_ ? 256U :
|
||||
afterglow_ ? 192U :
|
||||
sweep_ ? sweep_bins_per_block * sweep_block_count : 512U;
|
||||
waterfall_ ? 256U : afterglow_ ? 192U : sweep_ ? sweep_bins_per_block * sweep_block_count : 512U;
|
||||
std::vector<double> values(count);
|
||||
const std::uint64_t sample_sequence = sample_sequence_++;
|
||||
const std::uint64_t time_sequence = sweep_
|
||||
@@ -425,20 +405,19 @@ private:
|
||||
if (trace_) trace_->append_sample(current_time_of_day(), std::sin(time));
|
||||
if (constellation_) {
|
||||
constexpr std::size_t symbol_count =
|
||||
static_cast<std::size_t>(Constellation_Diagram_Type::Psk8);
|
||||
static_cast<std::size_t>(Constellation_Diagram_Type::Psk8);
|
||||
const std::size_t symbol_index = sample_sequence % symbol_count;
|
||||
const double phase = 2.0 * std::numbers::pi *
|
||||
static_cast<double>(symbol_index) /
|
||||
static_cast<double>(symbol_count);
|
||||
static_cast<double>(symbol_index) /
|
||||
static_cast<double>(symbol_count);
|
||||
const double i_noise =
|
||||
std::sin(time * 17.0 + static_cast<double>(symbol_index) * 0.73) * 0.04;
|
||||
std::sin(time * 17.0 + static_cast<double>(symbol_index) * 0.73) * 0.04;
|
||||
const double q_noise =
|
||||
std::cos(time * 19.0 + static_cast<double>(symbol_index) * 1.11) * 0.04;
|
||||
std::cos(time * 19.0 + static_cast<double>(symbol_index) * 1.11) * 0.04;
|
||||
constellation_->append_point(
|
||||
{std::cos(phase) + i_noise, std::sin(phase) + q_noise});
|
||||
}
|
||||
}
|
||||
|
||||
std::string case_id_;
|
||||
Size viewport_{560, 320};
|
||||
std::unique_ptr<Render_Scene_2D> scene_;
|
||||
@@ -458,7 +437,6 @@ private:
|
||||
std::uint64_t sample_sequence_{};
|
||||
};
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Gallery_Scene_Interface> make_gallery_scene_2d(
|
||||
std::uint64_t, std::string case_id, Gallery_Frame_Mode mode) {
|
||||
return std::make_unique<Gallery_Scene2D>(std::move(case_id), mode);
|
||||
|
||||
Reference in New Issue
Block a user