明面上没bug了

This commit is contained in:
2026-08-02 00:06:33 +08:00
parent e4772d9214
commit 85aecd0a06
36 changed files with 2994 additions and 1392 deletions
+17 -20
View File
@@ -6,6 +6,7 @@
#include <cmath>
#include <memory>
#include <memory_resource>
#include <rigtorp/MPMCQueue.h>
#include <system_error>
#include "../base/Memory.h"
#include "../render/Canvas.h"
@@ -19,7 +20,6 @@ struct Curve_Input_Data : Input_Data {};
struct Curve_Render_State : Render_State, Curve_Prop {};
struct Curve_Input_Block {
std::uint64_t sequence{};
Curve_Input_Mode mode = Curve_Input_Mode::None;
std::pmr::vector<double> samples{memory_resource(Memory_Domain::Curve)};
std::pmr::vector<PointF> points{memory_resource(Memory_Domain::Curve)};
@@ -172,10 +172,8 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
std::pmr::vector<double> samples{memory_resource(Memory_Domain::Curve)};
std::pmr::vector<PointF> data_points{memory_resource(Memory_Domain::Curve)};
Curve_Input_Mode mode = Curve_Input_Mode::None;
std::array<std::atomic<std::shared_ptr<Curve_Input_Block>>, Input_Queue_Capacity> input_slots;
std::atomic<std::uint64_t> input_write_sequence{0};
std::atomic<std::uint64_t> input_consumed_sequence{0};
std::uint64_t input_read_sequence{};
rigtorp::MPMCQueue<std::shared_ptr<Curve_Input_Block>> input_queue;
std::atomic_uint64_t dropped_input_count{0};
std::pmr::vector<std::shared_ptr<Update_State>> pending_geometry_update_states{memory_resource(Memory_Domain::Update_Completion)};
Curve_Geometry_Result geometry_result;
bool has_geometry_result{};
@@ -183,10 +181,13 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
bool has_submitted_geometry_key{};
std::uint64_t input_generation{};
Curve_Private()
: input_queue(Input_Queue_Capacity) {}
~Curve_Private() override {
complete_curve_result_states(geometry_result, std::make_error_code(std::errc::operation_canceled), Update_Outcome::Cancelled);
for (auto& slot : input_slots) {
auto block = slot.exchange({}, std::memory_order_acq_rel);
std::shared_ptr<Curve_Input_Block> block;
while (input_queue.try_pop(block)) {
if (block && block->completion_state)
block->completion_state->complete_all(std::make_error_code(std::errc::operation_canceled), Update_Outcome::Cancelled);
}
@@ -200,11 +201,12 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
void enqueue_input(std::shared_ptr<Curve_Input_Block> block) {
if (!block)
return;
std::uint64_t sequence = input_write_sequence.fetch_add(1, std::memory_order_acq_rel);
block->sequence = sequence;
auto replaced = input_slots[sequence % Input_Queue_Capacity].exchange(block, std::memory_order_acq_rel);
if (replaced && replaced->sequence >= input_consumed_sequence.load(std::memory_order_acquire) && replaced->completion_state)
replaced->completion_state->complete_all({}, Update_Outcome::Superseded);
if (!input_queue.try_push(block)) {
if (block->completion_state)
block->completion_state->complete_all({}, Update_Outcome::Superseded);
dropped_input_count.fetch_add(1, std::memory_order_relaxed);
return;
}
if (block->completion_state)
block->completion_state->complete_until(Update_Stage::Input_Released);
if (q())
@@ -212,20 +214,15 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
}
void consume_input_queue() {
std::uint64_t write_sequence = input_write_sequence.load(std::memory_order_acquire);
std::uint64_t first_sequence = write_sequence > Input_Queue_Capacity ? write_sequence - Input_Queue_Capacity : 0;
input_read_sequence = std::max(input_read_sequence, first_sequence);
std::shared_ptr<Curve_Input_Block> selected;
for (std::uint64_t sequence = input_read_sequence; sequence < write_sequence; ++sequence) {
auto block = input_slots[sequence % Input_Queue_Capacity].exchange({}, std::memory_order_acq_rel);
if (!block || block->sequence != sequence)
std::shared_ptr<Curve_Input_Block> block;
while (input_queue.try_pop(block)) {
if (!block)
continue;
if (selected && selected->completion_state)
selected->completion_state->complete_all({}, Update_Outcome::Superseded);
selected = std::move(block);
input_consumed_sequence.store(sequence + 1, std::memory_order_release);
}
input_read_sequence = write_sequence;
if (!selected)
return;
mode = selected->mode;