LCOV - code coverage report
Current view: top level - muse/framework/global/internal - tickerprovider.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 82.1 % 56 46
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2025 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include <QTimer>
      24              : 
      25              : #include "tickerprovider.h"
      26              : 
      27              : using namespace muse;
      28              : 
      29              : // heuristic value
      30              : static const int ONE_TICK_INTERVAL_MS = 16;
      31              : 
      32           46 : static uint32_t newTaskId()
      33              : {
      34              :     static uint32_t lastId = 0;
      35           46 :     ++lastId;
      36           46 :     return lastId;
      37              : }
      38              : 
      39           46 : void TickerProvider::start()
      40              : {
      41           46 :     m_ticks = 0;
      42           46 :     m_timer = std::make_shared<QTimer>();
      43           46 :     m_timer->setInterval(ONE_TICK_INTERVAL_MS);
      44           46 :     m_timer->setSingleShot(true);
      45           46 :     QObject::connect(m_timer.get(), &QTimer::timeout, [this]() {
      46          185 :         process();
      47          185 :     });
      48           46 :     m_timer->start();
      49           46 : }
      50              : 
      51           46 : void TickerProvider::stop()
      52              : {
      53           46 :     if (m_timer) {
      54           46 :         m_timer->stop();
      55           46 :         m_timer = nullptr;
      56              :     }
      57           46 : }
      58              : 
      59            0 : void TickerProvider::forceSchedule()
      60              : {
      61            0 :     if (!m_timer) {
      62            0 :         start();
      63            0 :     } else if (!m_timer->isActive()) {
      64            0 :         m_timer->start();
      65              :     }
      66            0 : }
      67              : 
      68          185 : void TickerProvider::addPending()
      69              : {
      70          189 :     for (const auto& p : m_pendingToAdd) {
      71            4 :         m_tasks.insert({ p.first, p.second });
      72              :     }
      73          185 :     m_pendingToAdd.clear();
      74          185 : }
      75              : 
      76          370 : void TickerProvider::removePending()
      77              : {
      78          370 :     for (uint32_t taskId : m_pendingToRemove) {
      79            0 :         auto it = m_tasks.find(taskId);
      80            0 :         if (it != m_tasks.end()) {
      81            0 :             m_tasks.erase(it);
      82              :         }
      83              :     }
      84          370 :     m_pendingToRemove.clear();
      85          370 : }
      86              : 
      87          185 : void TickerProvider::process()
      88              : {
      89          185 :     addPending();
      90              : 
      91          185 :     removePending();
      92              : 
      93          370 :     for (auto& p : m_tasks) {
      94          185 :         Task& task = p.second;
      95          185 :         if (task.interval == 0 || m_ticks % task.interval == 0) {
      96          185 :             task.call();
      97              : 
      98          185 :             if (!task.repeat) {
      99            0 :                 m_pendingToRemove.push_back(p.first);
     100              :             }
     101              :         }
     102              :     }
     103              : 
     104          185 :     removePending();
     105              : 
     106          185 :     ++m_ticks;
     107              : 
     108              :     // next iteration
     109          185 :     m_timer->start();
     110          185 : }
     111              : 
     112           46 : uint32_t TickerProvider::addTask(const Task& task)
     113              : {
     114           46 :     uint32_t taskId = newTaskId();
     115           46 :     m_pendingToAdd.insert({ taskId, task });
     116           46 :     return taskId;
     117              : }
     118              : 
     119           46 : void TickerProvider::removeTask(const uint32_t& taskId)
     120              : {
     121           46 :     m_pendingToRemove.push_back(taskId);
     122           46 : }
        

Generated by: LCOV version 2.0-1