361 lines
11 KiB
C++
361 lines
11 KiB
C++
/****************************************************************************
|
|
** ScStw Libraries
|
|
** Copyright (C) 2020 Itsblue development
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
****************************************************************************/
|
|
|
|
#ifndef SCSTWTIMER_H
|
|
#define SCSTWTIMER_H
|
|
|
|
#include <QObject>
|
|
#include <QDateTime>
|
|
#include <QDebug>
|
|
#include <QTimer>
|
|
#include "ScStw.hpp"
|
|
|
|
/*!
|
|
* \brief The ScStwTimer class is used for advanced time measurement.
|
|
*
|
|
* It does not work on its own though.
|
|
* It is recommended to use it in combination with the ScStwRace class.
|
|
*
|
|
* ## When using standalone:
|
|
*
|
|
* \code{.cpp}
|
|
* ScStwTimer timer;
|
|
* // start the timer
|
|
* timer.start();
|
|
* // stop the timer
|
|
* timer.stop();
|
|
* \endcode
|
|
*
|
|
* The timer will now go into ScStw::WAITING state.
|
|
* That indicates that the timer has stopped and the final result has to be assigned by an external handler.
|
|
*
|
|
* \code{.cpp}
|
|
* // assign result 'won'
|
|
* timer.setResult(ScStwTimer::WON);
|
|
* \endcode
|
|
*
|
|
* The timer is now in ScStwTimer::WON state.
|
|
*
|
|
* \code{.cpp}
|
|
* // reset the timer
|
|
* timer.reset();
|
|
* \endcode
|
|
*
|
|
* The timer is not in ScStwTimer::IDLE state again.
|
|
*/
|
|
class ScStwTimer : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/*!
|
|
* \brief ScStwTimer constructor
|
|
* \param parent the parent object
|
|
* \param directControlEnabled Defines if protected properties (startTimer, stopTime, reactionTime and state) can be directly set from outside.
|
|
* \param letter the letter of the timer (only first char will be used!)
|
|
*/
|
|
explicit ScStwTimer(QObject *parent = nullptr, bool directControlEnabled = false, QString letter = "" );
|
|
|
|
/*!
|
|
* \brief The TimerState enum contains all state the timer can be in
|
|
*/
|
|
enum TimerState {
|
|
IDLE, /*!< Timer is waiting to be started */
|
|
STARTING, /*!< Timer is starting and will react with a false start if the climber starts */
|
|
RUNNING, /*!< Timer is running */
|
|
WAITING, /*!< Timer was stopped and is waiting for the result */
|
|
WON, /*!< Timer has won */
|
|
LOST, /*!< Timer has lost */
|
|
FAILED, /*!< A false start occured */
|
|
CANCELLED, /*!< Timer was cancelled */
|
|
DISABLED /*!< Timer is disabled */
|
|
};
|
|
Q_ENUM(TimerState);
|
|
|
|
/*!
|
|
* \brief The StopReason enum contains all possible reasons for a stop
|
|
*/
|
|
enum StopReason {
|
|
ManualStop, /*!< Timer was stopped manually */
|
|
CancelStop, /*!< Timer was cancelled */
|
|
FailStop, /*!< A false start occured */
|
|
TopPadStop /*!< Timer was stopped by a physical trigger (eg. a ScStwExtension) */
|
|
};
|
|
|
|
protected:
|
|
/*!
|
|
* \brief The current state of the timer
|
|
*/
|
|
TimerState state;
|
|
|
|
/*!
|
|
* \brief The time the timer was started at
|
|
*/
|
|
double startTime;
|
|
|
|
/*!
|
|
* \brief The time the timer was stopped at
|
|
*/
|
|
double stopTime;
|
|
|
|
/*!
|
|
* \brief the reaction time of the climber
|
|
*/
|
|
double reactionTime;
|
|
|
|
/*!
|
|
* \brief Defines if protected properties (startTimer, stopTime, reactionTime and state) can be directly set from outside.
|
|
*/
|
|
bool directControlEnabled;
|
|
|
|
/*!
|
|
* \brief The letter (eg. "A" or "B") of the Timer (only one char)
|
|
*/
|
|
QString letter;
|
|
|
|
public slots:
|
|
|
|
/*!
|
|
* \brief Function to start the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::STARTING state!
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not started, true otherwise
|
|
*/
|
|
bool start();
|
|
|
|
/*!
|
|
* \brief Function to start the timer at a given point in time (present or future)
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::STARTING state!
|
|
*
|
|
* \param timeOfStart the point in time (msecs since epoch) when the timer is supposted to be started
|
|
* \return false if the timer was not in the required state and therefore not started, true otherwise
|
|
*/
|
|
virtual bool start(double timeOfStart);
|
|
|
|
/*!
|
|
* \brief Function to cancel the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::IDLE, ScStwTimer::STARTING or ScStwTimer::RUNNING state!
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not cancelled, true otherwise
|
|
*/
|
|
bool cancel();
|
|
|
|
/*!
|
|
* \brief Function to stop the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::RUNNING state!
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not stopped, true otherwise
|
|
*/
|
|
bool stop();
|
|
|
|
/*!
|
|
* \brief Function to stop the timer at a given point in time (past or future)
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::RUNNING state!
|
|
*
|
|
* \param timeOfStop the point in time (msecs since epoch) when the timer is supposted to be stopped
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not stopped, true otherwise
|
|
*/
|
|
bool stop(double timeOfStop);
|
|
|
|
/*!
|
|
* \brief Function to assing the result of the race to the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::WAITING state!
|
|
*
|
|
* \return false if the timer was not in the required state and the result therefore not set, true otherwise
|
|
*/
|
|
bool setResult(TimerState);
|
|
|
|
/*!
|
|
* \brief Function to reset the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::WON or ScSTw::LOST state!
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not reset, true otherwise
|
|
*/
|
|
virtual bool reset();
|
|
|
|
// -- helper functions --
|
|
/*!
|
|
* \brief Function to get the current state of the timer
|
|
* \return current state of the timer
|
|
* \see ScStwTimer::TimerState
|
|
*/
|
|
TimerState getState();
|
|
|
|
/*!
|
|
* \brief Function to get the current time of the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::RUNNING, ScStwTimer::WAITING, ScStwTimer::WON or ScSTw::LOST state!
|
|
*
|
|
* \return The current / final time of the timer or -1 if it is not in the required state
|
|
*/
|
|
double getCurrentTime();
|
|
|
|
/*!
|
|
* \brief Function to get the reaction time of the climber.
|
|
* \return The climbers reaction time
|
|
*/
|
|
double getReactionTime();
|
|
|
|
/*!
|
|
* \brief Function to get the text, a timer display is supposed to show
|
|
* \return The text to show
|
|
*/
|
|
QString getText();
|
|
|
|
/*!
|
|
* \brief Function to get the letter of the timer
|
|
* \return The letter of the timer or ""
|
|
*/
|
|
QString getLetter();
|
|
|
|
/*!
|
|
* \brief Function to set if the timer is supposed to be disabled
|
|
*
|
|
* !!! CAUTION use this function with care, it immidiately changes the state of the timer !!!
|
|
* It is recommended to only use this function to change the timers state after the
|
|
* ScStwTimer::requestTimerEnableChange() signal was called, during the race,
|
|
* the timer is used in, is in IDLE state.
|
|
*
|
|
* \param disabled if the timer is supposed to be diabled
|
|
*/
|
|
void setDisabled(bool disabled);
|
|
|
|
/*!
|
|
* \brief Function to change the state of the timer
|
|
*
|
|
* Only works when directControlEnabled is set to true!
|
|
* Doing this will emit the ScStwTimer::stateChanged() signal (only if the new state differs from the current one)
|
|
*
|
|
* \param newState The new state
|
|
* \param force whether to force the state change (just to distinguish between protected and public function)
|
|
* \return false when directControlEnabled or force is set to false and the startTime was therefore not modified, true otherwise
|
|
*/
|
|
bool setState(TimerState newState, bool force);
|
|
|
|
/*!
|
|
* \brief Function to dircetly change the start time
|
|
*
|
|
* Only works when directControlEnabled is set to true!
|
|
*
|
|
* \param startTime the time to change to
|
|
* \return false when directControlEnabled is set to false and the startTime was therefore not modified, true otherwise
|
|
*/
|
|
bool setStartTime(double startTime);
|
|
|
|
/*!
|
|
* \brief Function to dircetly change the stop time
|
|
*
|
|
* Only works when directControlEnabled is set to true!
|
|
*
|
|
* \param stopTime the time to change to
|
|
* \return false when directControlEnabled is set to false and the stopTime was therefore not modified, true otherwise
|
|
*/
|
|
bool setStopTime(double stopTime);
|
|
|
|
/*!
|
|
* \brief Function to dircetly change the rection time
|
|
*
|
|
* Only works when directControlEnabled is set to true!
|
|
*
|
|
* \param reactionTime the time to change to
|
|
* \return false when directControlEnabled is set to false and the reactionTime was therefore not modified, true otherwise
|
|
*/
|
|
bool setReactionTime(double rectionTime);
|
|
|
|
/*!
|
|
* \brief Function to dircetly change the letter
|
|
*
|
|
* Only works when directControlEnabled is set to true!
|
|
*
|
|
* \param newLetter the letter to change to
|
|
* \return false when directControlEnabled is set to false and the letter was therefore not modified, true otherwise
|
|
*/
|
|
bool setLetter(QString newLetter);
|
|
|
|
protected slots:
|
|
|
|
/*!
|
|
* \brief slot to call when the climber has started
|
|
* \param timeOfStart time (msecs since epoch) when the climber started
|
|
*/
|
|
void handleClimberStart(double timeOfStart);
|
|
|
|
/*!
|
|
* \brief Function to stop the timer at a given point in time (past or future)
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::RUNNING state!
|
|
*
|
|
* \param reason reason for the timer stop
|
|
* \param timeOfStop the point in time (msecs since epoch) when the timer is supposted to be stopped
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not stopped, true otherwise
|
|
*
|
|
* \see ScStwTimer::StopReason
|
|
*/
|
|
virtual bool stop(StopReason reason, double timeOfStop);
|
|
|
|
/*!
|
|
* \brief Function to stop the timer
|
|
*
|
|
* To do this, the timer has to be in ScStwTimer::RUNNING state!
|
|
*
|
|
* \param reason reason for the timer stop
|
|
*
|
|
* \return false if the timer was not in the required state and therefore not stopped, true otherwise
|
|
*
|
|
* \see ScStwTimer::StopReason
|
|
*/
|
|
bool stop(StopReason reason);
|
|
|
|
/*!
|
|
* \brief Function to change the state of the timer
|
|
*
|
|
* Doing this will emit the ScStwTimer::stateChanged() signal (only if the new state differs from the current one)
|
|
*
|
|
* \param newState The new state
|
|
*/
|
|
void setState(TimerState newState);
|
|
|
|
|
|
signals:
|
|
/*!
|
|
* \brief Emitted when the state of the timer changed
|
|
*/
|
|
void stateChanged();
|
|
|
|
/*!
|
|
* \brief Emitted when the reaction time changed
|
|
*/
|
|
void reactionTimeChanged();
|
|
|
|
/*!
|
|
* \brief Emitted when the timer wants its state to be changed by the external handler
|
|
* \param timer the timer object
|
|
*/
|
|
void requestEnableChange(ScStwTimer* timer);
|
|
|
|
};
|
|
|
|
#endif // SCSTWTIMER_H
|