diff --git a/Core/Axis/Abs_Axis.cpp b/Core/Axis/Abs_Axis.cpp index 9683ed5..7bc1e4b 100644 --- a/Core/Axis/Abs_Axis.cpp +++ b/Core/Axis/Abs_Axis.cpp @@ -60,7 +60,7 @@ std::vector Abs_Axis_Private::create_sub_tick_vector(int sub_tick_count, for (int k = 1; k <= sub_tick_count; ++k) result.push_back(ticks.at(i - 1) + k * sub_tick_step); } - while (!result.empty() && !range.contain(result.back())) { + while (!result.empty() && !range.contains(result.back())) { result.pop_back(); } return result; diff --git a/Core/Axis/Abs_Axis_p.h b/Core/Axis/Abs_Axis_p.h index 4f18fc1..90d1702 100644 --- a/Core/Axis/Abs_Axis_p.h +++ b/Core/Axis/Abs_Axis_p.h @@ -39,12 +39,12 @@ struct Abs_Axis_Private : Typed_Render_Datacoord_start, s->coord_start + s->coord_length}; double tick_step = get_tick_step(range); std::vector ticks = create_tick_vector(tick_step, range); - while (!ticks.empty() && !range.contain(ticks.back())) { + while (!ticks.empty() && !range.contains(ticks.back())) { ticks.pop_back(); } int sub_tick_count = get_sub_tick_count(tick_step); std::vector sub_ticks = create_sub_tick_vector(sub_tick_count, ticks, range); - while (!sub_ticks.empty() && !range.contain(sub_ticks.back())) { + while (!sub_ticks.empty() && !range.contains(sub_ticks.back())) { sub_ticks.pop_back(); } std::vector labels = create_label_vector(ticks, State_Render); diff --git a/Core/Axis/Time_Axis.cpp b/Core/Axis/Time_Axis.cpp index 38623b6..a358638 100644 --- a/Core/Axis/Time_Axis.cpp +++ b/Core/Axis/Time_Axis.cpp @@ -23,11 +23,11 @@ std::shared_ptr Time_Axis::timeline_stream() { void Time_Axis::set_timeline_stream(std::shared_ptr value) { d()->set_state_value(&Time_Axis_Render_State::timeline_stream, std::move(value)); } -bool Time_Axis::start_coord_to_end_coord() { - return d()->edit_state_value(&Time_Axis_Render_State::start_coord_to_end_coord); +bool Time_Axis::newest_at_axis_start() { + return d()->edit_state_value(&Time_Axis_Render_State::newest_at_axis_start); } -void Time_Axis::set_start_coord_to_end_coord(bool value) { - d()->set_state_value(&Time_Axis_Render_State::start_coord_to_end_coord, value); +void Time_Axis::set_newest_at_axis_start(bool value) { + d()->set_state_value(&Time_Axis_Render_State::newest_at_axis_start, value); } int Time_Axis::append_time(Time_Of_Day time) { if (!ok()) @@ -42,7 +42,7 @@ int Time_Axis::append_time(Time_Of_Day time) { Time_Of_Day Time_Axis::tick_to_time(int tick) { auto stream = timeline_stream(); if (stream) - return stream->capture(visible_time_point_count(), d()->state_data(State_Edit)->label_tick_interval_hint(), start_coord_to_end_coord()).time_by_tick(tick); + return stream->capture(visible_time_point_count(), d()->state_data(State_Edit)->label_tick_interval_hint(), newest_at_axis_start()).time_by_tick(tick); return d()->time_by_tick(tick); } Time_Axis::Builder::Builder(std::shared_ptr parent, Orientation orientation) { @@ -60,7 +60,7 @@ std::shared_ptr Time_Axis::Builder::build() { PROP_R(std::string, time_format) PROP_R(Font, font) PROP_R(std::shared_ptr, timeline_stream) - PROP_R(bool, start_coord_to_end_coord) + PROP_R(bool, newest_at_axis_start) sc->visible_time_point_count = std::max(1, sc->visible_time_point_count); sc->tick_label_spacing_px = std::max(1, sc->tick_label_spacing_px); if (!sc->timeline_stream) diff --git a/Core/Axis/Time_Axis.h b/Core/Axis/Time_Axis.h index 655b7cc..325fafc 100644 --- a/Core/Axis/Time_Axis.h +++ b/Core/Axis/Time_Axis.h @@ -20,7 +20,7 @@ public: PROP(std::string, time_format) PROP(Font, font) PROP(std::shared_ptr, timeline_stream) - PROP(bool, start_coord_to_end_coord) + PROP(bool, newest_at_axis_start) /// 推入一个新的时间点并返回对应 tick。 int append_time(Time_Of_Day time); /// 将 tick 转换成时间。 @@ -36,7 +36,7 @@ struct Time_Axis_Prop { std::string time_format = "mm:ss.zzz"; Font font; std::shared_ptr timeline_stream; - bool start_coord_to_end_coord = false; + bool newest_at_axis_start = false; }; struct LIB_DECL Time_Axis::Builder : Abs_Axis::Builder_T, public @@ -46,7 +46,7 @@ struct LIB_DECL Time_Axis::Builder : Abs_Axis::Builder_T, PROP_B(std::string, time_format) PROP_B(Font, font) PROP_B(std::shared_ptr, timeline_stream) - PROP_B(bool, start_coord_to_end_coord) + PROP_B(bool, newest_at_axis_start) /// 创建时间轴构造器。 Builder(std::shared_ptr parent, Orientation orientation); /// 构建并返回时间轴对象。 diff --git a/Core/Axis/Time_Axis_p.h b/Core/Axis/Time_Axis_p.h index e0669fd..a6191bb 100644 --- a/Core/Axis/Time_Axis_p.h +++ b/Core/Axis/Time_Axis_p.h @@ -29,7 +29,7 @@ struct Time_Axis_Private : Typed_Render_Data_Base capture_timeline(const Plot_Render_Snapshot& snapshot, const Time_Axis_Render_State* state) const { if (!state || !state->timeline_stream) return {}; - return snapshot.timeline_snapshot(state->timeline_stream, state->visible_time_point_count, state->label_tick_interval_hint(), state->start_coord_to_end_coord); + return snapshot.timeline_snapshot(state->timeline_stream, state->visible_time_point_count, state->label_tick_interval_hint(), state->newest_at_axis_start); } std::shared_ptr capture_timeline(const Plot_Render_Snapshot& snapshot) { sync_state_pipeline(); @@ -44,7 +44,7 @@ struct Time_Axis_Private : Typed_Render_Data_Basecoord_start = timeline_snapshot->coordinate_begin; - s->coord_length = timeline_snapshot->time_point_size; + s->coord_length = timeline_snapshot->visible_time_point_count; ticks.clear(); for (const Timeline_Label_Tick& tick : timeline_snapshot->ticks) { ticks.push_back(tick.coordinate); diff --git a/Core/architecture/Plot_Render_Context.cpp b/Core/architecture/Plot_Render_Context.cpp index 111a044..7c19112 100644 --- a/Core/architecture/Plot_Render_Context.cpp +++ b/Core/architecture/Plot_Render_Context.cpp @@ -2,19 +2,19 @@ #include "Timeline_Stream.h" #include namespace renderive { -std::shared_ptr Plot_Render_Snapshot::timeline_snapshot(const std::shared_ptr& stream, int time_point_size, int tick_space, bool start_coord_to_end_coord) const { +std::shared_ptr Plot_Render_Snapshot::timeline_snapshot(const std::shared_ptr& stream, int time_point_size, int label_tick_interval, bool start_coord_to_end_coord) const { if (!stream) return {}; time_point_size = std::max(1, time_point_size); - tick_space = std::max(1, tick_space); + label_tick_interval = std::max(1, label_tick_interval); if (!timeline_cache) timeline_cache = std::make_shared(); for (auto& item : timeline_cache->items) { - if (item.stream.lock() == stream && item.time_point_size == time_point_size && item.tick_space == tick_space && item.start_coord_to_end_coord == start_coord_to_end_coord) + if (item.stream.lock() == stream && item.time_point_size == time_point_size && item.tick_space == label_tick_interval && item.start_coord_to_end_coord == start_coord_to_end_coord) return item.snapshot; } - auto snapshot = std::make_shared(stream->capture(time_point_size, tick_space, start_coord_to_end_coord)); - timeline_cache->items.push_back({stream, time_point_size, tick_space, start_coord_to_end_coord, snapshot}); + auto snapshot = std::make_shared(stream->capture(time_point_size, label_tick_interval, start_coord_to_end_coord)); + timeline_cache->items.push_back({stream, time_point_size, label_tick_interval, start_coord_to_end_coord, snapshot}); return snapshot; } } diff --git a/Core/architecture/Plot_Render_Context.h b/Core/architecture/Plot_Render_Context.h index f58811c..2fb6152 100644 --- a/Core/architecture/Plot_Render_Context.h +++ b/Core/architecture/Plot_Render_Context.h @@ -60,7 +60,7 @@ struct Plot_Render_Snapshot { bool destroying() const { return !context || context->destroying.load(std::memory_order_acquire); } - std::shared_ptr timeline_snapshot(const std::shared_ptr& stream, int time_point_size, int tick_space, bool start_coord_to_end_coord) const; + std::shared_ptr timeline_snapshot(const std::shared_ptr& stream, int time_point_size, int label_tick_interval, bool start_coord_to_end_coord) const; }; } // namespace renderive diff --git a/Core/architecture/Renderable.h b/Core/architecture/Renderable.h index 21eed3e..ec90bf5 100644 --- a/Core/architecture/Renderable.h +++ b/Core/architecture/Renderable.h @@ -20,12 +20,9 @@ #include #include #include - namespace renderive { - class Plot_Core; class Renderable; - struct Renderable_Tree_Node { std::shared_ptr renderable; std::size_t subtree_end{}; @@ -34,9 +31,7 @@ struct Renderable_Tree_Node { std::string cache_parent_object_name; int cache_tree_depth{}; }; - using Renderable_Tree_Snapshot = std::vector; - template concept Render_State_Type = std::derived_from && std::is_copy_assignable_v; template @@ -46,8 +41,7 @@ concept Render_Data_Type = std::derived_from; template struct Renderable_Binding; template -struct Hover_Info_Renderable; - +struct Hover_Tooltip_Mixin; class Renderable : public std::enable_shared_from_this { public: virtual Render_Object_Owner create_render_data() { @@ -59,23 +53,18 @@ public: virtual Render_Object_Owner create_input_data() { return make_render_object(); } - virtual void init(const std::shared_ptr& parent); virtual void init_root(Plot_Core* plot); - void add_child(const std::shared_ptr& child); void remove_child(const std::shared_ptr& child); - std::vector> children_snapshot() const; std::vector> hit_renderables(const PointF& pos); void append_tree_snapshot(Renderable_Tree_Snapshot& snapshot, const std::string& parent_object_name = {}, int render_tree_depth = 0, const std::string& cache_parent_object_name = {}, int cache_tree_depth = 0); - void render(Canvas& canvas, const Plot_Render_Snapshot& snapshot); void render_tree_snapshot(Canvas& canvas, const Plot_Render_Snapshot& snapshot, const Renderable_Tree_Snapshot& tree, std::size_t index); void draw(Canvas& canvas, const Plot_Render_Snapshot& snapshot); void prepare_data(const Plot_Render_Snapshot& snapshot); bool select_test(const PointF& pos); - void plot_event(const Event& event); void mouse_press_event(const Pointer_Event& event); void mouse_move_event(const Pointer_Event& event); @@ -85,7 +74,6 @@ public: void key_release_event(const Key_Event& event); void resize_event(const Resize_Event& event); void wheel_event(const Wheel_Event& event); - Renderable_Cache_Mode get_cache_mode() const; void set_cache_mode(Renderable_Cache_Mode mode); [[nodiscard]] bool attached_to_plot() const; @@ -96,24 +84,19 @@ public: void set_visible(bool value); [[nodiscard]] bool should_prepare() const; void detach_from_parent(); - std::string cache_parent_object_name() const; int cache_tree_depth() const; std::string render_parent_object_name() const; int render_tree_depth() const; - void mark_render_dirty(); - [[nodiscard]] bool ok() const; [[nodiscard]] bool get_retiring() const; virtual ~Renderable(); - private: template friend struct Renderable_Binding; template - friend struct Hover_Info_Renderable; - + friend struct Hover_Tooltip_Mixin; Render_Object_Owner d_owner; Render_Data* d_ptr{}; Plot_Core* plot{}; @@ -131,7 +114,6 @@ private: Rect cache_bounds; std::atomic_bool retiring{true}; std::atomic_bool initialized{false}; - void init_common(Plot_Core* plot); void render_direct(Canvas& canvas, const Plot_Render_Snapshot& snapshot); void render_cached(Canvas& canvas, const Plot_Render_Snapshot& snapshot); @@ -146,5 +128,4 @@ private: void append_hit_renderables(std::vector>& hits, const PointF& pos); void detach_from_plot_tree(); }; - } // namespace renderive diff --git a/Core/architecture/Timeline_Stream.cpp b/Core/architecture/Timeline_Stream.cpp index 87a50da..d41ef09 100644 --- a/Core/architecture/Timeline_Stream.cpp +++ b/Core/architecture/Timeline_Stream.cpp @@ -4,7 +4,7 @@ #include namespace renderive { int Timeline_Stream_Snapshot::coordinate_end() const { - return coordinate_begin + time_point_size - 1; + return coordinate_begin + visible_time_point_count - 1; } bool Timeline_Stream_Snapshot::coord_by_stream_tick(int stream_tick, int& coord) const { if (times.empty()) @@ -15,13 +15,13 @@ bool Timeline_Stream_Snapshot::coord_by_stream_tick(int stream_tick, int& coord) if (newest_at_axis_start) coord = coordinate_begin + (last_stream_tick - stream_tick); else - coord = coordinate_begin + (time_point_size - count) + (stream_tick - first_stream_tick); + coord = coordinate_begin + (visible_time_point_count - count) + (stream_tick - first_stream_tick); return coord >= coordinate_begin && coord <= coordinate_end(); } Time_Of_Day Timeline_Stream_Snapshot::time_by_tick(int tick) const { int offset = tick - coordinate_begin; int count = static_cast(times.size()); - int index = newest_at_axis_start ? count - 1 - offset : offset - (time_point_size - count); + int index = newest_at_axis_start ? count - 1 - offset : offset - (visible_time_point_count - count); if (index < 0 || index >= count) return {}; return times[static_cast(index)]; @@ -59,7 +59,7 @@ Timeline_Stream_Snapshot Timeline_Stream::capture(int time_point_size, int label captured.push_back(*it); } snapshot.newest_at_axis_start = start_coord_to_end_coord; - snapshot.time_point_size = time_point_size; + snapshot.visible_time_point_count = time_point_size; if (captured.empty()) { snapshot.coordinate_begin = 0; return snapshot; diff --git a/Core/architecture/Timeline_Stream.h b/Core/architecture/Timeline_Stream.h index 13a9429..fddbb63 100644 --- a/Core/architecture/Timeline_Stream.h +++ b/Core/architecture/Timeline_Stream.h @@ -16,7 +16,7 @@ struct LIB_DECL Timeline_Stream_Snapshot { std::uint64_t version{}; bool newest_at_axis_start = false; // 当前 true 时 代表最新时间映射到起始坐标 int coordinate_begin{}; - int time_point_size = 1; + int visible_time_point_count = 1; int first_stream_tick{}; int last_stream_tick = -1; std::vector times; diff --git a/Core/base/Geometry.h b/Core/base/Geometry.h index 71b8318..18d4b5f 100644 --- a/Core/base/Geometry.h +++ b/Core/base/Geometry.h @@ -125,7 +125,7 @@ struct Range { bool operator!=(const Range& other) const { return !(*this == other); } - [[nodiscard]] bool contain(double value) const { + [[nodiscard]] bool contains(double value) const { if (origin < target) return value > origin - 0.0001 && value < target + 0.0001; return value > target - 0.0001 && value < origin + 0.0001; diff --git a/Core/plottable/Constellation_Diagram.cpp b/Core/plottable/Constellation_Diagram.cpp index c148d79..873ecc1 100644 --- a/Core/plottable/Constellation_Diagram.cpp +++ b/Core/plottable/Constellation_Diagram.cpp @@ -4,7 +4,7 @@ #include "../base/Memory.h" #include "Constellation_Diagram_p.h" namespace renderive { -RENDERIVE_DEFINE_RENDERABLE_BINDING(Constellation_Diagram, Constellation_Diagram_Private, Constellation_Diagram_State, Constellation_Diagram_Input_Data, "Planisphere") +RENDERIVE_DEFINE_RENDERABLE_BINDING(Constellation_Diagram, Constellation_Diagram_Private, Constellation_Diagram_State, Constellation_Diagram_Input_Data, "Constellation_Diagram") std::shared_ptr Constellation_Diagram::i_axis() { return d()->edit_state_value(&Constellation_Diagram_State::i_axis).lock(); } diff --git a/Core/plottable/Constellation_Diagram.h b/Core/plottable/Constellation_Diagram.h index 83118d4..7297def 100644 --- a/Core/plottable/Constellation_Diagram.h +++ b/Core/plottable/Constellation_Diagram.h @@ -50,7 +50,7 @@ private: Render_Object_Owner create_render_state() override; Render_Object_Owner create_input_data() override; }; -struct Planisphere_Prop { +struct Constellation_Diagram_Prop { std::weak_ptr i_axis{}; std::weak_ptr q_axis{}; Range i_range{0, 100}; @@ -62,7 +62,7 @@ struct Planisphere_Prop { double phase_offset_radians = 0.0; }; /// @brief 星座图构造器。 -struct LIB_DECL Constellation_Diagram::Builder : Planisphere_Prop { +struct LIB_DECL Constellation_Diagram::Builder : Constellation_Diagram_Prop { PROP_B(std::shared_ptr, parent) PROP_B(std::shared_ptr, i_axis) PROP_B(std::shared_ptr, q_axis) diff --git a/Core/plottable/Constellation_Diagram_p.h b/Core/plottable/Constellation_Diagram_p.h index a5d3dcc..f9a2697 100644 --- a/Core/plottable/Constellation_Diagram_p.h +++ b/Core/plottable/Constellation_Diagram_p.h @@ -45,7 +45,7 @@ struct Constellation_Diagram_Input_Data : Input_Data { data_list.clear(); } }; -struct Constellation_Diagram_State : Render_State, Planisphere_Prop {}; +struct Constellation_Diagram_State : Render_State, Constellation_Diagram_Prop {}; struct Constellation_Diagram_Private : Typed_Render_Data { std::pmr::list data_list{memory_resource(Memory_Domain::Constellation_Diagram)}; std::pmr::vector prepared_points{memory_resource(Memory_Domain::Constellation_Diagram)}; diff --git a/Core/plottable/Frequency_Trace.cpp b/Core/plottable/Frequency_Trace.cpp index 25ed80c..d422d5a 100644 --- a/Core/plottable/Frequency_Trace.cpp +++ b/Core/plottable/Frequency_Trace.cpp @@ -2,18 +2,18 @@ #include "Frequency_Trace_p.h" #include "../base/Memory.h" namespace renderive { -RENDERIVE_DEFINE_RENDERABLE_BINDING(Frequency_Trace, Frequency_Trace_Private, Audio_Frequency_Render_State, Audio_Frequency_Input_Data, "Audio_Frequency") +RENDERIVE_DEFINE_RENDERABLE_BINDING(Frequency_Trace, Frequency_Trace_Private, Frequency_Trace_Render_State, Frequency_Trace_Input_Data, "Frequency_Trace") std::shared_ptr Frequency_Trace::time_axis() { - return d()->edit_state_value(&Audio_Frequency_Render_State::time_axis).lock(); + return d()->edit_state_value(&Frequency_Trace_Render_State::time_axis).lock(); } void Frequency_Trace::set_time_axis(std::shared_ptr value) { - d()->set_state_value(&Audio_Frequency_Render_State::time_axis, std::weak_ptr(value)); + d()->set_state_value(&Frequency_Trace_Render_State::time_axis, std::weak_ptr(value)); } std::shared_ptr Frequency_Trace::value_axis() { - return d()->edit_state_value(&Audio_Frequency_Render_State::value_axis).lock(); + return d()->edit_state_value(&Frequency_Trace_Render_State::value_axis).lock(); } void Frequency_Trace::set_value_axis(std::shared_ptr value) { - d()->set_state_value(&Audio_Frequency_Render_State::value_axis, std::weak_ptr(value)); + d()->set_state_value(&Frequency_Trace_Render_State::value_axis, std::weak_ptr(value)); } Frequency_Trace::Builder::Builder(std::shared_ptr parent, std::shared_ptr time_axis, std::shared_ptr value_axis) { ASSERT(parent && parent->attached_to_plot(), "Audio_Frequency build error! parent invalid"); @@ -30,7 +30,7 @@ std::shared_ptr Frequency_Trace::Builder::build() { auto ret = renderive::make_shared(); ret->init(parent); Frequency_Trace_Private* pd = ret->d(); - Audio_Frequency_Render_State* sc = reinterpret_cast(pd->state(State_Edit)); + Frequency_Trace_Render_State* sc = reinterpret_cast(pd->state(State_Edit)); PROP_R(std::weak_ptr, time_axis) PROP_R(std::weak_ptr, value_axis) sc->pen = Pen{.color = color, .width = 1.0}; @@ -39,7 +39,7 @@ std::shared_ptr Frequency_Trace::Builder::build() { void Frequency_Trace::append_sample(int tick, double data) { if (!ok()) return; - Render_Input_Lease input(d()); + Render_Input_Lease input(d()); input->push(tick, data); } void Frequency_Trace::append_sample(Time_Of_Day time, double data) { @@ -52,7 +52,7 @@ void Frequency_Trace::append_sample(Time_Of_Day time, double data) { if (!stream) return; int tick = stream->append_time(time); - Render_Input_Lease input(d()); + Render_Input_Lease input(d()); input->push(tick, data); } } // namespace renderive diff --git a/Core/plottable/Frequency_Trace_p.h b/Core/plottable/Frequency_Trace_p.h index ba561aa..4ed3f38 100644 --- a/Core/plottable/Frequency_Trace_p.h +++ b/Core/plottable/Frequency_Trace_p.h @@ -11,22 +11,22 @@ #include "Psc_Cpp_Core/Base/RingBuffer.hpp" #include "Frequency_Trace.h" namespace renderive { -struct Audio_Frequency_Data { +struct Frequency_Sample { int tick{}; double power{}; }; -struct Audio_Frequency_Input_Data : Input_Data { +struct Frequency_Trace_Input_Data : Input_Data { static constexpr std::size_t Max_Pending_Value_Count = 256; Bounded_Input_Buffer data_list; void push(int tick, double power) { - Audio_Frequency_Data data{tick, power}; + Frequency_Sample data{tick, power}; data_list.push(&data, sizeof(data), Max_Pending_Value_Count); } template void read_all(Handler handler) { data_list.read_all([&handler](const void* data, std::size_t size) { (void)size; - Audio_Frequency_Data value; + Frequency_Sample value; std::memcpy(&value, data, sizeof(value)); handler(value); }); @@ -35,10 +35,10 @@ struct Audio_Frequency_Input_Data : Input_Data { data_list.clear(); } }; -struct Audio_Frequency_Render_State : Render_State, Frequency_Trace_Prop {}; -struct Frequency_Trace_Private : Typed_Render_Data { +struct Frequency_Trace_Render_State : Render_State, Frequency_Trace_Prop {}; +struct Frequency_Trace_Private : Typed_Render_Data { Psc::StreamRingBuffer_ST buffer{memory_resource(Memory_Domain::Audio)}; - std::pmr::vector data_snapshot{memory_resource(Memory_Domain::Audio)}; + std::pmr::vector data_snapshot{memory_resource(Memory_Domain::Audio)}; std::pmr::vector prepared_points{memory_resource(Memory_Domain::Audio)}; int data_count{}; int point_count{}; @@ -46,12 +46,12 @@ struct Frequency_Trace_Private : Typed_Render_Datatime_axis.lock(); auto value_axis = s->value_axis.lock(); if (!time_axis || !value_axis) @@ -72,16 +72,16 @@ struct Frequency_Trace_Private : Typed_Render_Datatime_point_size) - resize_power_buffer(timeline->time_point_size); - d->read_all([this](const Audio_Frequency_Data& data) { + if (point_count != timeline->visible_time_point_count) + resize_power_buffer(timeline->visible_time_point_count); + d->read_all([this](const Frequency_Sample& data) { push_power(data); }); snapshot_power_buffer(); prepared_points.clear(); prepared_points.reserve(static_cast(data_count)); for (int i = 0; i < data_count; ++i) { - const Audio_Frequency_Data& item = data_snapshot[static_cast(i)]; + const Frequency_Sample& item = data_snapshot[static_cast(i)]; int coord{}; if (timeline->coord_by_stream_tick(item.tick, coord)) prepared_points.emplace_back(static_cast(coord), item.power); @@ -89,7 +89,7 @@ struct Frequency_Trace_Private : Typed_Render_Datatime_axis.lock(); auto value_axis = s->value_axis.lock(); if (!time_axis || !value_axis || prepared_points.empty()) diff --git a/Core/plottable/Hover_Tooltip.h b/Core/plottable/Hover_Tooltip.h index cbb9c27..f8fd3f3 100644 --- a/Core/plottable/Hover_Tooltip.h +++ b/Core/plottable/Hover_Tooltip.h @@ -134,7 +134,7 @@ private: virtual Hover_State_Edit begin_hover_edit_impl() = 0; }; template -struct LIB_DECL Hover_Info_Renderable : Hover_Tooltip_Provider { +struct LIB_DECL Hover_Tooltip_Mixin : Hover_Tooltip_Provider { private: That* that() { return static_cast(this); diff --git a/Core/plottable/Spectrum.cpp b/Core/plottable/Spectrum.cpp index 8673312..5d673d2 100644 --- a/Core/plottable/Spectrum.cpp +++ b/Core/plottable/Spectrum.cpp @@ -279,7 +279,7 @@ void Spectrum_Private::set_frequency_data(std::pmr::vector& line_data, c min_marker_value = cur_powers[min_index]; } double Spectrum_Private::get_y(double x, bool& ok, Line_Interpolation_Mode mode) { - if (cur_powers.size() < 2 || cache_frequency_range.length() == 0.0 || !cache_frequency_range.contain(x)) { + if (cur_powers.size() < 2 || cache_frequency_range.length() == 0.0 || !cache_frequency_range.contains(x)) { ok = false; return -1; } diff --git a/Core/plottable/Spectrum.h b/Core/plottable/Spectrum.h index f918d64..e17232f 100644 --- a/Core/plottable/Spectrum.h +++ b/Core/plottable/Spectrum.h @@ -16,7 +16,7 @@ struct Spectrum_Private; class Label; class Marker; /// @brief 单条频谱线图元,支持可见范围裁剪和多种线插值策略。 -class LIB_DECL Spectrum : public Renderable, public Hover_Info_Renderable { +class LIB_DECL Spectrum : public Renderable, public Hover_Tooltip_Mixin { public: /// @brief 创建频谱线图元。 Spectrum(); diff --git a/Core/plottable/Waterfall.h b/Core/plottable/Waterfall.h index 2082a18..8277107 100644 --- a/Core/plottable/Waterfall.h +++ b/Core/plottable/Waterfall.h @@ -25,7 +25,7 @@ enum class Waterfall_Row_Update_Policy : std::uint8_t { Rate_Limited_Latest }; /// @brief 瀑布图图元,按时间行保存二维频谱强度。 -class LIB_DECL Waterfall : public Renderable, public Hover_Info_Renderable { +class LIB_DECL Waterfall : public Renderable, public Hover_Tooltip_Mixin { public: /// @brief 创建瀑布图图元。 Waterfall(); diff --git a/Core/plottable/Waterfall_p.h b/Core/plottable/Waterfall_p.h index 2ce8f6a..2b745d1 100644 --- a/Core/plottable/Waterfall_p.h +++ b/Core/plottable/Waterfall_p.h @@ -368,7 +368,7 @@ struct Waterfall_Private : Typed_Render_Datafrequency_bin_count, row_count = timeline->time_point_size; + int col_count = s->frequency_bin_count, row_count = timeline->visible_time_point_count; if (col_count <= 0 || row_count <= 0) return; if (!ring_buffer.match(col_count, row_count)) { @@ -454,12 +454,12 @@ struct Waterfall_Private : Typed_Render_Datacolor_scale.snapshot(); Abs_Axis* h_axis = frequency_axis.get(); Range h_range = s->frequency_range; - Range v_range{static_cast(timeline.coordinate_begin), static_cast(timeline.coordinate_begin + timeline.time_point_size)}; + Range v_range{static_cast(timeline.coordinate_begin), static_cast(timeline.coordinate_begin + timeline.visible_time_point_count)}; if (s->visible_range_only && !intersect_range(s->frequency_range, Axis_Render_Access::coord_range(h_axis), h_range)) { image_draw_visible = false; return; } - int col_count = s->frequency_bin_count, row_count = timeline.time_point_size; + int col_count = s->frequency_bin_count, row_count = timeline.visible_time_point_count; if (col_count <= 0 || row_count <= 0 || s->frequency_range.length() == 0.0 || color_scale->range.size() == 0.0) return; double source_start = static_cast(col_count) * (h_range.origin - s->frequency_range.origin) / s->frequency_range.length(); diff --git a/test/Renderive_Core_Tests.cpp b/test/Renderive_Core_Tests.cpp index b07c286..7bdb784 100644 --- a/test/Renderive_Core_Tests.cpp +++ b/test/Renderive_Core_Tests.cpp @@ -13,10 +13,8 @@ #include #include #include - namespace renderive { namespace { - bool unique_roles(const Triple_Buffer_View& view) { std::array seen{}; for (std::uint8_t index : view.index) { @@ -26,7 +24,6 @@ bool unique_roles(const Triple_Buffer_View& view) { } return true; } - Frame_Lifecycle_Record render_frame(std::uint64_t begin_ns, std::uint64_t end_ns) { Frame_Lifecycle_Record frame; frame.render_role_enter_ns = begin_ns; @@ -34,7 +31,6 @@ Frame_Lifecycle_Record render_frame(std::uint64_t begin_ns, std::uint64_t end_ns frame.render_end_ns = end_ns; return frame; } - bool wait_until(std::function predicate) { auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2); while (std::chrono::steady_clock::now() < deadline) { @@ -44,7 +40,6 @@ bool wait_until(std::function predicate) { } return predicate(); } - std::shared_ptr performance_frame(std::uint64_t frame_id, int width = 240, int height = 80) { auto frame = std::make_shared(); frame->frame_id = frame_id; @@ -68,7 +63,6 @@ std::shared_ptr performance_frame(std::uint64_t frame_id frame->worker.executor_at_finish.completed_task_nodes = frame_id; return frame; } - bool valid_utf8(const std::string& text) { for (std::size_t i = 0; i < text.size();) { unsigned char c = static_cast(text[i]); @@ -93,16 +87,13 @@ bool valid_utf8(const std::string& text) { } return true; } - } // namespace - TEST(Renderive_Canvas, TextUsesPenAndFillUsesBrush) { auto diagnostics = Canvas::default_font_diagnostics(); ASSERT_TRUE(diagnostics.face_valid); ASSERT_TRUE(diagnostics.font_valid); ASSERT_GT(diagnostics.test_width, 0.0); ASSERT_GT(diagnostics.test_height, 0.0); - Image image(400, 100); image.fill(Color::transparent()); { @@ -113,7 +104,6 @@ TEST(Renderive_Canvas, TextUsesPenAndFillUsesBrush) { canvas.draw_text(PointF{10.0, 10.0}, "0123456789 ABC \xE4\xB8\xAD\xE6\x96\x87"); canvas.draw_text(RectF{10.0, 50.0, 300.0, 30.0}, Text_Align::Left | Text_Align::Top, "0123"); } - EXPECT_EQ(premultiplied_to_color(image.row(2)[2]), Color::white()); int dark_pixels = 0; for (int y = 8; y < 82; ++y) { @@ -127,18 +117,15 @@ TEST(Renderive_Canvas, TextUsesPenAndFillUsesBrush) { } EXPECT_GT(dark_pixels, 20); } - TEST(Renderive_Triple_Buffer, RoleSwapsAreTryOnlyAndDeterministic) { Triple_Role_Buffer_Control control; control.reset(); EXPECT_TRUE(unique_roles(control.read_view())); - auto first = control.try_swap_role(Frame_Rendering, Frame_Middle, [](const Triple_Buffer_View&) { return true; }); EXPECT_EQ(first.result, Triple_Buffer_Result::Success); EXPECT_TRUE(unique_roles(control.read_view())); - auto painting = control.try_acquire_role(Frame_Painting); ASSERT_EQ(painting.result, Triple_Buffer_Result::Success); auto blocked = control.try_swap_role(Frame_Middle, Frame_Painting, [](const Triple_Buffer_View&) { @@ -146,7 +133,6 @@ TEST(Renderive_Triple_Buffer, RoleSwapsAreTryOnlyAndDeterministic) { }); EXPECT_EQ(blocked.result, Triple_Buffer_Result::Busy); control.unmark_use(painting.lease); - for (int i = 0; i < 1000000; ++i) { auto a = control.try_swap_role(Frame_Rendering, Frame_Middle, [](const Triple_Buffer_View&) { return true; @@ -159,7 +145,6 @@ TEST(Renderive_Triple_Buffer, RoleSwapsAreTryOnlyAndDeterministic) { ASSERT_TRUE(unique_roles(control.read_view())); } } - TEST(Renderive_Frame_Pipeline, PublishAndPaintUseMiddleVersionOnly) { Plot_Frame_Pipeline pipeline; auto lease = pipeline.try_acquire_render_frame(); @@ -170,18 +155,15 @@ TEST(Renderive_Frame_Pipeline, PublishAndPaintUseMiddleVersionOnly) { lease.frame->metadata->render_end_ns = 20; lease.frame->version.store(1, std::memory_order_release); lease.reset(); - auto published = pipeline.try_publish_rendered_frame(25); EXPECT_TRUE(pipeline.middle_frame_ready()); EXPECT_TRUE(published.request_present); EXPECT_EQ(published.dropped_frame_record, nullptr); - auto painting = pipeline.try_acquire_paint_frame(30); EXPECT_TRUE(painting.has_new_frame); EXPECT_TRUE(static_cast(painting.lease)); EXPECT_FALSE(pipeline.middle_frame_ready()); } - TEST(Renderive_Frame_Pipeline, PaintAcquireFailureKeepsPendingRequest) { Plot_Frame_Pipeline pipeline; auto lease = pipeline.try_acquire_render_frame(); @@ -192,11 +174,9 @@ TEST(Renderive_Frame_Pipeline, PaintAcquireFailureKeepsPendingRequest) { lease.frame->metadata->render_end_ns = 20; lease.frame->version.store(1, std::memory_order_release); lease.reset(); - auto published = pipeline.try_publish_rendered_frame(25); ASSERT_TRUE(published.request_present); EXPECT_TRUE(pipeline.paint_request_pending.load(std::memory_order_acquire)); - auto busy = pipeline.frame_control.try_acquire_role(Frame_Painting); ASSERT_EQ(busy.result, Triple_Buffer_Result::Success); auto failed = pipeline.try_acquire_paint_frame(30); @@ -204,18 +184,15 @@ TEST(Renderive_Frame_Pipeline, PaintAcquireFailureKeepsPendingRequest) { EXPECT_FALSE(failed.present_request_was_pending); EXPECT_TRUE(pipeline.paint_request_pending.load(std::memory_order_acquire)); pipeline.frame_control.unmark_use(busy.lease); - auto consumed = pipeline.try_acquire_paint_frame(35); EXPECT_TRUE(consumed.present_request_was_pending); EXPECT_TRUE(static_cast(consumed.lease)); } - TEST(Renderive_MPMCQueue, UsesTryOnlyBoundedCapacity) { rigtorp::MPMCQueue queue(2); EXPECT_TRUE(queue.try_push(1)); EXPECT_TRUE(queue.try_push(2)); EXPECT_FALSE(queue.try_push(3)); - int value = 0; EXPECT_TRUE(queue.try_pop(value)); EXPECT_EQ(value, 1); @@ -223,7 +200,6 @@ TEST(Renderive_MPMCQueue, UsesTryOnlyBoundedCapacity) { EXPECT_EQ(value, 2); EXPECT_FALSE(queue.try_pop(value)); } - TEST(Renderive_Frame_Feedback, SelectsRenderPaintAndUserSources) { Frame_Feedback_Controller controller; controller.set_max_render_fps(200.0); @@ -232,7 +208,6 @@ TEST(Renderive_Frame_Feedback, SelectsRenderPaintAndUserSources) { controller.on_render_completed(render_limited); } EXPECT_EQ(controller.state().source, Refresh_Limit_Source::Render); - controller.reset(); controller.set_max_render_fps(200.0); for (int i = 0; i < 4; ++i) { @@ -244,7 +219,6 @@ TEST(Renderive_Frame_Feedback, SelectsRenderPaintAndUserSources) { controller.on_frame_presented(frame); } EXPECT_EQ(controller.state().source, Refresh_Limit_Source::Paint); - controller.reset(); controller.set_max_render_fps(30.0); for (int i = 0; i < 4; ++i) { @@ -256,7 +230,6 @@ TEST(Renderive_Frame_Feedback, SelectsRenderPaintAndUserSources) { } EXPECT_EQ(controller.state().source, Refresh_Limit_Source::User); } - TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) { Render_Executor executor(Render_Runtime_Config{1}); std::atomic_bool entered{false}; @@ -270,19 +243,19 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) { Task([&]() { entered.store(true, std::memory_order_release); while (!release.load(std::memory_order_acquire)) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - }), + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + }), {}, Task([&]() { completed.fetch_add(1, std::memory_order_acq_rel); - }), + }), first_stat, 1, true - })); + })); ASSERT_TRUE(wait_until([&]() { return entered.load(std::memory_order_acquire); - })); + })); auto second_stat = std::make_shared(); EXPECT_TRUE(executor.try_submit(Render_Executor_Task{ 2, @@ -292,11 +265,11 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) { {}, Task([&]() { completed.fetch_add(1, std::memory_order_acq_rel); - }), + }), second_stat, 1, true - })); + })); auto third_stat = std::make_shared(); EXPECT_TRUE(executor.try_submit(Render_Executor_Task{ 3, @@ -306,11 +279,11 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) { {}, Task([&]() { completed.fetch_add(1, std::memory_order_acq_rel); - }), + }), third_stat, 1, true - })); + })); auto duplicate_stat = std::make_shared(); EXPECT_FALSE(executor.try_submit(Render_Executor_Task{ 2, @@ -322,7 +295,7 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) { duplicate_stat, 1, true - })); + })); auto overflow_stat = std::make_shared(); EXPECT_FALSE(executor.try_submit(Render_Executor_Task{ 4, @@ -334,66 +307,61 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) { overflow_stat, 1, true - })); + })); release.store(true, std::memory_order_release); ASSERT_TRUE(wait_until([&]() { return completed.load(std::memory_order_acquire) == 3; - })); + })); executor.shutdown(); } - TEST(Renderive_Render_Executor, TaskflowTopologyRunsInFrameOrder) { Render_Executor executor(Render_Runtime_Config{2}); std::atomic_int sequence{0}; std::atomic_bool completed{false}; auto stat = std::make_shared(); - ASSERT_TRUE(executor.try_submit(Render_Executor_Task{ 1, 1, Render_Task_Kind::Frame, Task{}, [&sequence](tf::Taskflow& taskflow, tf::Task entry, tf::Task exit) { - auto prepare = taskflow.emplace([&sequence]() { - int expected = 0; - sequence.compare_exchange_strong(expected, 1, std::memory_order_acq_rel); + auto prepare = taskflow.emplace([&sequence]() { + int expected = 0; + sequence.compare_exchange_strong(expected, 1, std::memory_order_acq_rel); }); - auto draw = taskflow.emplace([&sequence]() { - int expected = 1; - sequence.compare_exchange_strong(expected, 2, std::memory_order_acq_rel); + auto draw = taskflow.emplace([&sequence]() { + int expected = 1; + sequence.compare_exchange_strong(expected, 2, std::memory_order_acq_rel); }); - auto finalize = taskflow.emplace([&sequence]() { - int expected = 2; - sequence.compare_exchange_strong(expected, 3, std::memory_order_acq_rel); + auto finalize = taskflow.emplace([&sequence]() { + int expected = 2; + sequence.compare_exchange_strong(expected, 3, std::memory_order_acq_rel); }); - entry.precede(prepare); - prepare.precede(draw); - draw.precede(finalize); - finalize.precede(exit); + entry.precede(prepare); + prepare.precede(draw); + draw.precede(finalize); + finalize.precede(exit); }, Task([&completed]() { completed.store(true, std::memory_order_release); - }), + }), stat, 3, true - })); - + })); ASSERT_TRUE(wait_until([&]() { return completed.load(std::memory_order_acquire); - })); + })); EXPECT_EQ(sequence.load(std::memory_order_acquire), 3); EXPECT_EQ(stat->task_count, 3u); executor.shutdown(); } - TEST(Renderive_Render_Executor, QueuedFramesRunRoundRobinByPlot) { Render_Executor executor(Render_Runtime_Config{1}); std::atomic_bool first_entered{false}; std::atomic_bool release_first{false}; std::atomic_int order_index{0}; std::array order{}; - ASSERT_TRUE(executor.try_submit(Render_Executor_Task{ 1, 1, @@ -401,56 +369,53 @@ TEST(Renderive_Render_Executor, QueuedFramesRunRoundRobinByPlot) { Task([&]() { first_entered.store(true, std::memory_order_release); while (!release_first.load(std::memory_order_acquire)) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); order[order_index.fetch_add(1, std::memory_order_acq_rel)] = 1; - }), + }), {}, Task([]() {}), std::make_shared(), 1, true - })); + })); ASSERT_TRUE(wait_until([&]() { return first_entered.load(std::memory_order_acquire); - })); - + })); ASSERT_TRUE(executor.try_submit(Render_Executor_Task{ 2, 1, Render_Task_Kind::Frame, Task([&]() { order[order_index.fetch_add(1, std::memory_order_acq_rel)] = 2; - }), + }), {}, Task([]() {}), std::make_shared(), 1, true - })); + })); ASSERT_TRUE(executor.try_submit(Render_Executor_Task{ 3, 1, Render_Task_Kind::Frame, Task([&]() { order[order_index.fetch_add(1, std::memory_order_acq_rel)] = 3; - }), + }), {}, Task([]() {}), std::make_shared(), 1, true - })); - + })); release_first.store(true, std::memory_order_release); ASSERT_TRUE(wait_until([&]() { return order_index.load(std::memory_order_acquire) == 3; - })); + })); EXPECT_EQ(order[0], 1); EXPECT_EQ(order[1], 2); EXPECT_EQ(order[2], 3); executor.shutdown(); } - TEST(Renderive_Performance_Shower, ToggleDoesNotReenterRenderableTreeUnsafely) { Plot_Core plot(std::make_unique()); plot.init(); @@ -464,7 +429,6 @@ TEST(Renderive_Performance_Shower, ToggleDoesNotReenterRenderableTreeUnsafely) { EXPECT_FALSE(performance_overlay_enabled(plot)); EXPECT_TRUE(root->children_snapshot().empty()); } - TEST(Renderive_Performance_Shower, TogglePreservesAttachedOptions) { Plot_Core plot(std::make_unique()); plot.init(); @@ -472,7 +436,6 @@ TEST(Renderive_Performance_Shower, TogglePreservesAttachedOptions) { options.font.size = 17.0; options.background = Color{10, 20, 30, 255}; options.foreground = Color{240, 240, 240, 255}; - auto original = attach_performance_overlay(plot, options); ASSERT_TRUE(original); set_performance_overlay_enabled(plot, true); @@ -480,21 +443,18 @@ TEST(Renderive_Performance_Shower, TogglePreservesAttachedOptions) { set_performance_overlay_enabled(plot, false); EXPECT_FALSE(performance_overlay_enabled(plot)); set_performance_overlay_enabled(plot, true); - auto toggled = performance_overlay(plot); ASSERT_EQ(toggled, original); EXPECT_EQ(toggled->options().font.size, options.font.size); EXPECT_EQ(toggled->options().background, options.background); EXPECT_EQ(toggled->options().foreground, options.foreground); } - -TEST(Renderive_Hover_Info, DefaultTextPenContrastsWithDefaultBackground) { +TEST(Renderive_Hover_Tooltip, DefaultTextPenContrastsWithDefaultBackground) { Hover_Tooltip_State state; EXPECT_EQ(state.tooltip_background_brush.color, Color::white()); EXPECT_EQ(state.tooltip_text_pen.color, Color::black()); } - -TEST(Renderive_Performance_Shower, WorkerConsumesSharedFrameRecord) { +TEST(Renderive_Performance_Overlay, WorkerConsumesSharedFrameRecord) { auto state = std::make_shared(); state->enabled.store(true, std::memory_order_release); auto frame = std::make_shared(); @@ -511,7 +471,6 @@ TEST(Renderive_Performance_Shower, WorkerConsumesSharedFrameRecord) { frame->outcome = Frame_Outcome::Presented; Performance_Frame_Record record = frame; ASSERT_TRUE(state->metric_queue.try_push(record)); - schedule_performance_metrics_worker(state); auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2); std::shared_ptr snapshot; @@ -522,13 +481,11 @@ TEST(Renderive_Performance_Shower, WorkerConsumesSharedFrameRecord) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } state->cancelled.store(true, std::memory_order_release); - ASSERT_TRUE(snapshot); EXPECT_FALSE(snapshot->lines.empty()); EXPECT_TRUE(state->aggregate.has_frame); EXPECT_EQ(state->aggregate.latest.frame_id, 7); } - TEST(Renderive_Performance_Shower, OptionsAffectSnapshotRendering) { Performance_Overlay shower; Performance_Overlay_Options options; @@ -539,11 +496,10 @@ TEST(Renderive_Performance_Shower, OptionsAffectSnapshotRendering) { shower.set_enabled(true); shower.set_viewport(Size{260, 120}, 1); shower.collect_frame(performance_frame(1, 260, 120)); - ASSERT_TRUE(wait_until([&]() { auto snapshot = shower.display_snapshot(); return snapshot && !snapshot->image.empty(); - })); + })); auto snapshot = shower.display_snapshot(); ASSERT_TRUE(snapshot); ASSERT_FALSE(snapshot->image.empty()); @@ -551,35 +507,31 @@ TEST(Renderive_Performance_Shower, OptionsAffectSnapshotRendering) { EXPECT_GT(snapshot->line_height, 12.0); EXPECT_EQ(premultiplied_to_color(snapshot->image.row(1)[1]), options.background); } - TEST(Renderive_Performance_Shower, OutcomeWidthIsSeededWithLongestEnumText) { auto state = std::make_shared(); state->enabled.store(true, std::memory_order_release); auto outcome_width = [&]() { return state->field_layout_states[static_cast(Performance_Metric_Id::Outcome)].max_value_width; }; - auto presented = performance_frame(1, 260, 120); presented->outcome = Frame_Outcome::Presented; ASSERT_TRUE(state->metric_queue.try_push(Performance_Frame_Record{presented})); schedule_performance_metrics_worker(state); ASSERT_TRUE(wait_until([&]() { return state->aggregate.latest.frame_id == 1 && !state->worker_active.load(std::memory_order_acquire); - })); + })); double seeded_width = outcome_width(); EXPECT_GT(seeded_width, 0.0); - auto dropped = performance_frame(2, 260, 120); dropped->outcome = Frame_Outcome::Worker_Budget_Dropped; ASSERT_TRUE(state->metric_queue.try_push(Performance_Frame_Record{dropped})); schedule_performance_metrics_worker(state); ASSERT_TRUE(wait_until([&]() { return state->aggregate.latest.frame_id == 2 && !state->worker_active.load(std::memory_order_acquire); - })); + })); EXPECT_EQ(outcome_width(), seeded_width); state->cancelled.store(true, std::memory_order_release); } - TEST(Renderive_Performance_Shower, NumericFieldWidthIsMonotonicAcrossResetAndResize) { auto state = std::make_shared(); state->enabled.store(true, std::memory_order_release); @@ -595,7 +547,7 @@ TEST(Renderive_Performance_Shower, NumericFieldWidthIsMonotonicAcrossResetAndRes ASSERT_TRUE(wait_until([&]() { auto snapshot = state->published_snapshot.load(std::memory_order_acquire); return snapshot && state->aggregate.latest.frame_id == frame_id && !state->worker_active.load(std::memory_order_acquire); - })); + })); double current = frame_width(); EXPECT_GE(current, previous); previous = current; @@ -604,14 +556,12 @@ TEST(Renderive_Performance_Shower, NumericFieldWidthIsMonotonicAcrossResetAndRes if (frame_id == 2 || frame_id == 8) EXPECT_EQ(current, wide); } - state->reset_requested.store(true, std::memory_order_release); schedule_performance_metrics_worker(state); ASSERT_TRUE(wait_until([&]() { return !state->worker_active.load(std::memory_order_acquire); - })); + })); EXPECT_EQ(frame_width(), wide); - state->viewport_width.store(180, std::memory_order_release); state->viewport_height.store(90, std::memory_order_release); state->viewport_version.store(2, std::memory_order_release); @@ -620,11 +570,10 @@ TEST(Renderive_Performance_Shower, NumericFieldWidthIsMonotonicAcrossResetAndRes ASSERT_TRUE(wait_until([&]() { auto snapshot = state->published_snapshot.load(std::memory_order_acquire); return snapshot && snapshot->viewport_version == 2 && !state->worker_active.load(std::memory_order_acquire); - })); + })); EXPECT_EQ(frame_width(), wide); state->cancelled.store(true, std::memory_order_release); } - TEST(Renderive_Performance_Shower, ScrollCommandsUpdateOffsetAndClamp) { Performance_Overlay shower; shower.set_enabled(true); @@ -634,16 +583,14 @@ TEST(Renderive_Performance_Shower, ScrollCommandsUpdateOffsetAndClamp) { ASSERT_TRUE(wait_until([&]() { auto snapshot = shower.display_snapshot(); return snapshot && snapshot->max_scroll_offset > 0.0; - })); - + })); auto snapshot = shower.display_snapshot(); ASSERT_TRUE(snapshot); EXPECT_TRUE(shower.handle_wheel(PointF{5.0, 5.0}, -120.0, 0.0)); ASSERT_TRUE(wait_until([&]() { auto next = shower.display_snapshot(); return next && next->scroll_offset > snapshot->scroll_offset; - })); - + })); snapshot = shower.display_snapshot(); ASSERT_TRUE(snapshot); PointF page_down{snapshot->scroll_track_rect.x + 1.0, snapshot->scroll_thumb_rect.bottom() + 1.0}; @@ -651,8 +598,7 @@ TEST(Renderive_Performance_Shower, ScrollCommandsUpdateOffsetAndClamp) { ASSERT_TRUE(wait_until([&]() { auto next = shower.display_snapshot(); return next && next->scroll_offset > snapshot->scroll_offset; - })); - + })); snapshot = shower.display_snapshot(); ASSERT_TRUE(snapshot); PointF thumb_center{snapshot->scroll_thumb_rect.x + 1.0, snapshot->scroll_thumb_rect.y + snapshot->scroll_thumb_rect.height * 0.5}; @@ -662,9 +608,8 @@ TEST(Renderive_Performance_Shower, ScrollCommandsUpdateOffsetAndClamp) { ASSERT_TRUE(wait_until([&]() { auto next = shower.display_snapshot(); return next && next->max_scroll_offset > 0.0 && next->scroll_offset > next->max_scroll_offset * 0.8; - })); + })); } - TEST(Renderive_Performance_Shower, Utf8WrappingKeepsValidText) { Performance_Overlay shower; shower.set_enabled(true); @@ -680,15 +625,13 @@ TEST(Renderive_Performance_Shower, Utf8WrappingKeepsValidText) { ASSERT_TRUE(wait_until([&]() { auto snapshot = shower.display_snapshot(); return snapshot && !snapshot->lines.empty(); - })); + })); auto snapshot = shower.display_snapshot(); ASSERT_TRUE(snapshot); for (const auto& line : snapshot->lines) EXPECT_TRUE(valid_utf8(line)) << line; } - } // namespace renderive - int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();