Какой подход, паттерн выбрать для обработки данных?

Здравствуйте!

Пишу на С++/Qt.

Есть набор данных ("сырой"), построен его график. Пользователь может выделить окно на этом графике для обработки.
Обработка данных - последовательность операций - сглаживание, усреднение, производная, вторая производная, свертка и другие преобразования. Каждая операция занимает некоторое время - 1-2 секунды.
Обработка идет на лету, пользователь изменил что-то - сразу пересчитываются все операции.

Вопрос в том, как прекратить выполнение последовательности операций, если пользователь постоянно меняет окно на графике?
Есть операции, когда используется сырой набор данных и набор после обработки. Получается сырой набор уже изменился, а некий набор после обработки еще старый.

Как-то сделать можно, флаги ввести, мьютексы или еще чего.
Хочется красивого, возможно сто раз описанного похода.

Здесь хранятся наборы данных после каждой операции:
typedef std::vector<Graph> GraphSet;
std::map<Set, GraphSet> m_fullDataSet;


enum class Set
{
    Raw,
    Smooth,
    Window,
    Average,
    Variance,
    Gauss
};


Вот типовая операция. После завершения эмитирую сигнал:
void Calculator::accumulatedAverage()
{
    m_fullDataSet[Set::Average].clear();

    const GraphSet & windowSet = m_fullDataSet[Set::Window];

    for (const Graph & graph: windowSet)
    {
        Curve average;
        average.x = graph.curve.x;

        double sum = 0;
        double amount = 0;
        for (double point: graph.curve.y)
        {
            sum += point; // накапливаем сумму точек
            amount += 1; // количество точек

            average.y.push_back(sum/amount);
        }
        m_fullDataSet[Set::Average].push_back(Graph(graph.name, "", average, graph.color));
    }
    emit averageSetChanged();
}


Последовательность операций задается так:
void Calculator::path()
{
    connect(this, &Calculator::rawSetChanged,        this, [&](){ smoothData(Set::Raw, Set::Smooth); },                          Qt::QueuedConnection);
    connect(this, &Calculator::smoothSetChanged,     this, [&](Set set){ if (set == Set::Smooth) pickGraphs(); }, Qt::QueuedConnection);
    connect(this, &Calculator::bordersChanged,       this, [&](){ if (m_border1 != m_border2) cutWindow(); }, Qt::QueuedConnection);
    connect(this, &Calculator::windowSetChanged,     this, [&](){ accumulatedAverage(); }, Qt::QueuedConnection);
    connect(this, &Calculator::averageSetChanged,    this, [&](){ variance(); }, Qt::QueuedConnection);
    connect(this, &Calculator::varianceSetChanged,   this, [&](){ gauss(); }, Qt::QueuedConnection);
}
  • Вопрос задан
  • 3054 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы