File indexing completed on 2024-05-19 16:51:55

0001 /*
0002     Copyright (C) 2014 by Elvis Angelaccio <elvis.angelaccio@kde.org>
0003 
0004     This file is part of Kronometer.
0005 
0006     Kronometer is free software: you can redistribute it and/or modify
0007     it under the terms of the GNU General Public License as published by
0008     the Free Software Foundation, either version 2 of the License, or
0009     (at your option) any later version.
0010 
0011     Kronometer is distributed in the hope that it will be useful,
0012     but WITHOUT ANY WARRANTY; without even the implied warranty of
0013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014     GNU General Public License for more details.
0015 
0016     You should have received a copy of the GNU General Public License
0017     along with Kronometer.  If not, see <http://www.gnu.org/licenses/>.
0018 */
0019 
0020 #ifndef STOPWATCH_H
0021 #define STOPWATCH_H
0022 
0023 #include <QElapsedTimer>
0024 #include <QObject>
0025 #include <QTime>
0026 
0027 class QTimerEvent;
0028 
0029 /**
0030  * @brief A Stopwatch class.
0031  * Stopwatch is a simple QObject implementing a real stopwatch.
0032  * The class provides public slots to start/pause/reset its internal timer.
0033  * A slot for laps recording exists too, but the computing of lap times is not a task of this class:
0034  * Stopwatch simply emits a signal, that the receiver can use to compute lap times.
0035  */
0036 class Stopwatch : public QObject
0037 {
0038     Q_OBJECT
0039 
0040 public:
0041 
0042     enum class Granularity : int
0043     {
0044         Milliseconds = 1, /**< Stopwatch refreshed every msec. */
0045         Hundredths = 10,  /**< Stopwatch refreshed every 10 msec. */
0046         Tenths = 100,     /**< Stopwatch refreshed every 100 msec. */
0047         Seconds = 1000   /**< Stopwatch refreshed every sec. */
0048     };
0049 
0050     explicit Stopwatch(QObject *parent = nullptr);
0051 
0052     /**
0053      * Set the stopwatch refresh granularity
0054      * @param g The granularity to be set.
0055      */
0056     void setGranularity(Granularity g);
0057 
0058     /**
0059      * Check if the stopwatch is running
0060      * @return true if running, false otherwise
0061      */
0062     bool isRunning() const;
0063 
0064     /**
0065      * Check if the stopwatch is paused
0066      * @return true if paused, false otherwise
0067      */
0068     bool isPaused() const;
0069 
0070     /**
0071      * Check if the stopwatch is inactive
0072      * @return true if inactive, false otherwise
0073      */
0074     bool isInactive() const;
0075 
0076     /**
0077      * Read-only access to the stopwatch underlying data
0078      * @return The stopwatch raw counter
0079      */
0080     int raw() const;
0081 
0082     /**
0083      * (Re)-initialize (deserialize) the stopwatch from the given raw data counter.
0084      * Only an inactive stopwatch is meant to be (re)-initialized (deserialized).
0085      * @param rawData The raw milliseconds counter for the stopwatch
0086      * @return true if the operation succeeds (i.e. the stopwatch was inactive), false otherwise
0087      */
0088     bool initialize(int rawData);
0089 
0090 public slots:
0091 
0092     /**
0093      * Start the stopwatch, if inactive or paused.
0094      */
0095     void start();
0096 
0097     /**
0098      * Pause the stopwatch, if running.
0099      */
0100     void pause();
0101 
0102     /**
0103      * Reset the stopwatch to the inactive state.
0104      */
0105     void reset();
0106 
0107     /**
0108      * Tells the stopwatch to compute a new lap time.
0109      */
0110     void storeLap();
0111 
0112 signals:
0113 
0114     /**
0115      * The stopwatch has been started.
0116      */
0117     void running();
0118 
0119     /**
0120      * The stopwatch has been paused.
0121      */
0122     void paused();
0123 
0124     /**
0125      * The stopwatch has been reset.
0126      */
0127     void inactive();
0128 
0129     /**
0130      * Emits a signal with the last lap *absolute* time.
0131      * This class does not compute *relatives* lap times.
0132      * You can compute them simply by the difference between consecutives absolute times.
0133      * @param lapTime The absolute time of the last lap.
0134      */
0135     void lap(const QTime& lapTime);
0136 
0137     /**
0138      * Emits a signal with the current stopwatch time.
0139      * @param t Current stopwatch time.
0140      */
0141     void time(int t);
0142 
0143 protected:
0144 
0145     void timerEvent(QTimerEvent *event) override;
0146 
0147 private:
0148 
0149     int granularity() const;
0150 
0151     enum class State
0152     {
0153         Inactive, /**< Inactive stopwatch. */
0154         Running,  /**< Running stopwatch. */
0155         Paused    /**< Paused stopwatch. */
0156     };
0157 
0158     static constexpr int INACTIVE_TIMER_ID = -1;    /** Used for timerId initialization */
0159 
0160     int m_timerId = INACTIVE_TIMER_ID;                      /** ID for the QObject timer */
0161     int m_accumulator = 0;                                  /** milliseconds internal counter */
0162     State m_state = State::Inactive;                        /** Stopwatch current state */
0163     Granularity m_granularity = Granularity::Hundredths;    /** Stopwatch current granularity */
0164 
0165     QElapsedTimer m_elapsedTimer;               /** Stopwatch core class*/
0166 
0167     Q_DISABLE_COPY(Stopwatch)
0168 };
0169 
0170 
0171 
0172 #endif