2020-06-07 14:43:47 +02:00
|
|
|
/****************************************************************************
|
|
|
|
** 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/>.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
#ifndef SCSTWTIMER_H
|
|
|
|
#define SCSTWTIMER_H
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QDebug>
|
2020-04-14 00:08:58 +02:00
|
|
|
#include <QTimer>
|
2020-04-11 23:41:34 +02:00
|
|
|
#include "ScStw.hpp"
|
|
|
|
|
2020-09-29 12:53:40 +02:00
|
|
|
class ScStwRace;
|
|
|
|
class ScStwRemoteRace;
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \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:
|
2020-04-19 13:09:24 +02:00
|
|
|
*
|
2020-04-15 19:21:32 +02:00
|
|
|
* \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.
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
class ScStwTimer : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief ScStwTimer constructor
|
|
|
|
* \param parent the parent object
|
2020-04-18 14:25:48 +02:00
|
|
|
* \param directControlEnabled Defines if protected properties (startTimer, stopTime, reactionTime and state) can be directly set from outside.
|
2020-06-13 12:38:24 +02:00
|
|
|
* \param letter the letter of the timer (only first char will be used!)
|
2020-04-15 19:21:32 +02:00
|
|
|
*/
|
2020-10-02 19:56:08 +02:00
|
|
|
explicit ScStwTimer(QObject *parent = nullptr, QString letter = "" );
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-09-29 12:53:40 +02:00
|
|
|
friend class ScStwRace;
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \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 */
|
2020-10-04 16:04:22 +02:00
|
|
|
WAITING, /*!< Timer was stopped and is waiting to be set to either WON or LOST */
|
2020-04-15 19:21:32 +02:00
|
|
|
WON, /*!< Timer has won */
|
|
|
|
LOST, /*!< Timer has lost */
|
2020-10-04 16:04:22 +02:00
|
|
|
FAILING, /*!< Timer encountered a false start and is waiting to be set to either FAILED or WILDCARD */
|
2020-10-04 15:22:43 +02:00
|
|
|
WILDCARD, /*!< The opponent has done a false start */
|
2020-10-04 16:04:22 +02:00
|
|
|
FAILED, /*!< A false start occured */
|
2020-04-15 19:21:32 +02:00
|
|
|
CANCELLED, /*!< Timer was cancelled */
|
2020-09-29 12:53:40 +02:00
|
|
|
INCIDENT, /*!< There was a technical incident (most likely a disconnected extension) */
|
2020-04-15 19:21:32 +02:00
|
|
|
DISABLED /*!< Timer is disabled */
|
|
|
|
};
|
2020-04-17 19:57:00 +02:00
|
|
|
Q_ENUM(TimerState);
|
2020-04-15 19:21:32 +02:00
|
|
|
|
2020-08-14 17:02:53 +02:00
|
|
|
/*!
|
|
|
|
* \brief The ReadyStatus enum contains all possible reasons for a timer not to be ready (>0) and the case that it is ready (0)
|
|
|
|
*/
|
|
|
|
enum ReadyState {
|
|
|
|
IsReady = 0, /*!< Timer is ready for start */
|
|
|
|
NotInIdleState, /*!< Timer is not in IDLE state */
|
|
|
|
IsDisabled, /*!< Timer is disabled */
|
2020-09-25 18:24:40 +02:00
|
|
|
ExtensionIsNotConnected, /*!< Not all extension of the timer are conneted */
|
|
|
|
ExtensionBatteryNotFine, /*!< The battery level of one or more extension is critical or unknown */
|
|
|
|
ClimberIsNotReady /*!< The startpad of the timer is not triggered */
|
2020-04-15 19:21:32 +02:00
|
|
|
};
|
2020-10-05 20:41:43 +02:00
|
|
|
Q_ENUM(ReadyState)
|
2020-04-11 23:41:34 +02:00
|
|
|
|
|
|
|
protected:
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief The current state of the timer
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
TimerState state;
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief The time the timer was started at
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
double startTime;
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief The time the timer was stopped at
|
|
|
|
*/
|
|
|
|
double stopTime;
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief the reaction time of the climber
|
|
|
|
*/
|
|
|
|
double reactionTime;
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-06-13 12:38:24 +02:00
|
|
|
/*!
|
|
|
|
* \brief The letter (eg. "A" or "B") of the Timer (only one char)
|
|
|
|
*/
|
|
|
|
QString letter;
|
|
|
|
|
2020-08-09 13:29:37 +02:00
|
|
|
/*!
|
|
|
|
* \brief Defines if the timer currently wants to be disabled or not
|
|
|
|
*/
|
|
|
|
bool wantsToBeDisabled;
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
public slots:
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
bool start();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-05-18 10:49:11 +02:00
|
|
|
virtual bool start(double timeOfStart);
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
bool cancel();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
bool stop();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-05-18 10:49:11 +02:00
|
|
|
virtual bool reset();
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
// -- helper functions --
|
|
|
|
/*!
|
|
|
|
* \brief Function to get the current state of the timer
|
|
|
|
* \return current state of the timer
|
|
|
|
* \see ScStwTimer::TimerState
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
TimerState getState();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
double getCurrentTime();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to get the reaction time of the climber.
|
|
|
|
* \return The climbers reaction time
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
double getReactionTime();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
2020-04-17 19:57:00 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to get the text, a timer display is supposed to show
|
|
|
|
* \return The text to show
|
|
|
|
*/
|
|
|
|
QString getText();
|
|
|
|
|
2020-06-13 12:38:24 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to get the letter of the timer
|
|
|
|
* \return The letter of the timer or ""
|
|
|
|
*/
|
|
|
|
QString getLetter();
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
void setDisabled(bool disabled);
|
|
|
|
|
2020-08-09 13:29:37 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to check if the timer currently wants to be disabled
|
|
|
|
* \return true or false
|
|
|
|
*/
|
|
|
|
bool getWantsToBeDisabled();
|
|
|
|
|
2020-08-14 17:02:53 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to get the current ready status of a timer
|
|
|
|
* \return The current ready status
|
|
|
|
*/
|
|
|
|
virtual ScStwTimer::ReadyState getReadyState();
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
protected slots:
|
|
|
|
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief slot to call when the climber has started
|
|
|
|
* \param timeOfStart time (msecs since epoch) when the climber started
|
|
|
|
*/
|
2020-04-14 00:08:58 +02:00
|
|
|
void handleClimberStart(double timeOfStart);
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \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
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
void setState(TimerState newState);
|
|
|
|
|
2020-08-09 13:29:37 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to set whether the timer currently wants to be disabled
|
|
|
|
* \param wantsToBeDisabled true or false
|
|
|
|
*/
|
|
|
|
void setWantsToBeDisabled(bool wantsToBeDisabled);
|
|
|
|
|
2020-09-29 12:53:40 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to set the timer into INCIDENT state immidieately
|
|
|
|
*
|
|
|
|
* The current state of the timer will be ignored! It can only get out of this state by calling ScStwTimer::reset
|
|
|
|
*
|
|
|
|
* \see reset
|
|
|
|
*/
|
|
|
|
void technicalIncident();
|
|
|
|
|
2020-10-04 15:22:43 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to set the timer into WILDCARD state
|
|
|
|
*
|
|
|
|
* Only works when the timer is in STARTING state.
|
|
|
|
*
|
|
|
|
* \return false if not in STARTING state
|
|
|
|
*/
|
|
|
|
bool wildcard();
|
|
|
|
|
2020-04-18 14:25:48 +02:00
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
signals:
|
2020-04-15 19:21:32 +02:00
|
|
|
/*!
|
|
|
|
* \brief Emitted when the state of the timer changed
|
|
|
|
*/
|
2020-10-04 16:31:49 +02:00
|
|
|
void stateChanged(TimerState state);
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Emitted when the reaction time changed
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
void reactionTimeChanged();
|
2020-04-15 19:21:32 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Emitted when the timer wants its state to be changed by the external handler
|
|
|
|
* \param timer the timer object
|
|
|
|
*/
|
2020-08-09 13:29:37 +02:00
|
|
|
void wantsToBeDisabledChanged(ScStwTimer* timer, bool wantsToBeDisabled);
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-08-14 17:02:53 +02:00
|
|
|
/*!
|
|
|
|
* \brief Emitted when the ready state of the timer changes
|
|
|
|
* \param readyState the new ReadyState
|
|
|
|
*/
|
|
|
|
void readyStateChanged(ReadyState readyState);
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // SCSTWTIMER_H
|