明面上没bug了
This commit is contained in:
+17
-20
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user