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 SCSTWRACE_H
|
|
|
|
#define SCSTWRACE_H
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QEventLoop>
|
|
|
|
#include "scstwtimer.h"
|
|
|
|
#include "scstwsoundplayer.h"
|
2020-10-03 15:15:49 +02:00
|
|
|
#include "scstwsettings.h"
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-10-03 11:10:15 +02:00
|
|
|
class ScStwRemoteRace;
|
|
|
|
|
2020-04-19 13:09:24 +02:00
|
|
|
/*!
|
|
|
|
* \brief The ScStwRace class can be used to measure timings of climbing races with multiple lanes at once.
|
|
|
|
*
|
|
|
|
* The ScStwRace is a container to manage multiple timers at a time and introduces a propper start sequence
|
|
|
|
* with start commands ('At your Marks' and 'Ready') and the official IFSC start signal.
|
|
|
|
*
|
|
|
|
* ## Basic usage:
|
|
|
|
*
|
|
|
|
* \code
|
|
|
|
* ScStwRace race;
|
|
|
|
*
|
|
|
|
* // add two timers
|
|
|
|
* race.addTimer(new ScStwTimer());
|
|
|
|
* race.addTimer(new ScStwTimer());
|
|
|
|
*
|
|
|
|
* // start a race
|
|
|
|
* race.start();
|
|
|
|
* \endcode
|
|
|
|
*
|
|
|
|
*/
|
2020-04-11 23:41:34 +02:00
|
|
|
class ScStwRace : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
2020-04-15 21:47:04 +02:00
|
|
|
Q_PROPERTY(RaceState state READ getState NOTIFY stateChanged)
|
2020-10-05 20:41:43 +02:00
|
|
|
Q_PROPERTY(QVariantList timers READ getTimerDetailList NOTIFY timersChanged)
|
2020-10-03 11:44:56 +02:00
|
|
|
Q_PROPERTY(QVariantMap currentStartDelay READ getCurrentStartDelay NOTIFY currentStartDelayChanged)
|
2020-10-03 11:10:15 +02:00
|
|
|
Q_PROPERTY(bool isReadyForNextState READ getIsReadyForNextState NOTIFY isReadyForNextStateChanged)
|
2020-10-03 11:44:56 +02:00
|
|
|
Q_PROPERTY(bool competitionMode READ getCompetitionMode NOTIFY competitionModeChanged)
|
|
|
|
Q_PROPERTY(bool readySoundEnabled READ getReadySoundEnabled NOTIFY readySoundEnabledChanged)
|
2020-10-02 19:53:07 +02:00
|
|
|
Q_PROPERTY(QVariantMap details READ getDetails NOTIFY detailsChanged)
|
2020-10-09 15:18:56 +02:00
|
|
|
Q_PROPERTY(ScStwSettings* settings READ getSettings WRITE setSettings NOTIFY settingsChanged)
|
|
|
|
Q_PROPERTY(bool autoRefreshTimerText READ getAutoRefreshTimerText WRITE setAutoRefreshTimerText NOTIFY autoRefreshTimerTextChanged)
|
2020-04-19 13:09:24 +02:00
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
public:
|
2020-10-09 15:18:56 +02:00
|
|
|
explicit ScStwRace(QObject *parent = nullptr);
|
2020-10-03 15:15:49 +02:00
|
|
|
explicit ScStwRace(ScStwSettings *settings, QObject *parent = nullptr);
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-10-03 11:10:15 +02:00
|
|
|
friend class ScStwRemoteRace;
|
|
|
|
|
2020-09-29 15:21:00 +02:00
|
|
|
enum RaceState { IDLE, PREPAIRING, WAITING, STARTING, RUNNING, STOPPED, INCIDENT };
|
2020-04-11 23:41:34 +02:00
|
|
|
Q_ENUM(RaceState)
|
|
|
|
|
2020-04-18 14:25:48 +02:00
|
|
|
protected:
|
|
|
|
QList<ScStwTimer *> timers;
|
|
|
|
void setState(RaceState newState);
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
private:
|
|
|
|
RaceState state;
|
|
|
|
|
2020-10-02 14:16:24 +02:00
|
|
|
QTimer *startDelayTimer;
|
2020-10-09 15:18:56 +02:00
|
|
|
QTimer *timerTextRefreshTimer;
|
2020-10-02 14:16:24 +02:00
|
|
|
QEventLoop *startWaitLoop;
|
2020-04-11 23:41:34 +02:00
|
|
|
|
|
|
|
// sounds
|
|
|
|
ScStwSoundPlayer * soundPlayer;
|
|
|
|
|
2020-10-03 15:15:49 +02:00
|
|
|
// settings
|
|
|
|
ScStwSettings *settings;
|
2020-10-02 14:16:24 +02:00
|
|
|
bool competitionMode;
|
2020-10-09 15:18:56 +02:00
|
|
|
bool autoRefreshTimerText;
|
2020-10-02 14:16:24 +02:00
|
|
|
|
|
|
|
enum LoopExitTypes {
|
|
|
|
LoopAutomaticExit = 0,
|
2020-10-04 01:47:50 +02:00
|
|
|
LoopReadyStateChangeExit = 1,
|
2020-10-02 14:16:24 +02:00
|
|
|
LoopManualExit = 2,
|
|
|
|
LoopCancelExit = 3
|
|
|
|
};
|
2020-04-11 23:41:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
public slots:
|
2020-04-19 22:39:33 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to start the race
|
|
|
|
*
|
|
|
|
* \param asyncronous if the function should just start the start sequence and then quit (true)
|
|
|
|
* or if if should wait until the start sequence is over and quit after that (false)
|
|
|
|
* \return 200: OK; 904: state not matching
|
|
|
|
*/
|
2020-10-02 15:20:11 +02:00
|
|
|
virtual ScStw::StatusCode start(bool asyncronous = true);
|
2020-04-19 22:39:33 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to stop the currently running race
|
|
|
|
*
|
|
|
|
* \return 200: OK; 904: state not matching
|
|
|
|
*/
|
2020-10-02 15:20:11 +02:00
|
|
|
virtual ScStw::StatusCode stop();
|
2020-04-19 22:39:33 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to reset a stopped race
|
|
|
|
* \return
|
|
|
|
*/
|
2020-10-02 15:20:11 +02:00
|
|
|
virtual ScStw::StatusCode reset();
|
|
|
|
virtual ScStw::StatusCode cancel();
|
2020-04-17 19:57:00 +02:00
|
|
|
|
2020-10-05 22:21:33 +02:00
|
|
|
virtual ScStw::StatusCode setTimerDisabled(int id, bool disabled);
|
|
|
|
|
2020-10-09 15:18:56 +02:00
|
|
|
Q_INVOKABLE virtual bool addTimer(ScStwTimer *timer);
|
2020-04-17 19:57:00 +02:00
|
|
|
|
|
|
|
// getters
|
2020-04-11 23:41:34 +02:00
|
|
|
RaceState getState();
|
2020-10-03 11:44:56 +02:00
|
|
|
virtual QVariantMap getCurrentStartDelay();
|
2020-07-29 17:56:32 +02:00
|
|
|
QList<ScStwTimer*> getTimers();
|
2020-04-11 23:41:34 +02:00
|
|
|
QVariantList getTimerDetailList();
|
2020-10-02 19:53:07 +02:00
|
|
|
QVariantMap getDetails();
|
2020-10-03 11:44:56 +02:00
|
|
|
bool getCompetitionMode();
|
2020-10-03 13:06:14 +02:00
|
|
|
virtual bool getReadySoundEnabled();
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-10-09 15:18:56 +02:00
|
|
|
ScStwSettings* getSettings();
|
|
|
|
void setSettings(ScStwSettings* settings);
|
|
|
|
|
|
|
|
bool getAutoRefreshTimerText();
|
|
|
|
void setAutoRefreshTimerText(bool autoRefresh);
|
|
|
|
|
2020-04-18 14:25:48 +02:00
|
|
|
protected slots:
|
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
private slots:
|
2020-10-04 16:31:49 +02:00
|
|
|
void handleTimerStateChange(ScStwTimer::TimerState newState);
|
2020-04-19 22:39:33 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Function to declare the winner and looser timers after a timer has been stopped
|
|
|
|
*/
|
2020-04-18 14:25:48 +02:00
|
|
|
void handleTimerStop();
|
2020-10-04 16:31:49 +02:00
|
|
|
void handleFalseStart();
|
|
|
|
|
|
|
|
|
|
|
|
void handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled);
|
|
|
|
bool playSoundsAndStartTimers();
|
|
|
|
ScStwSoundPlayer::PlayResult doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart = nullptr);
|
|
|
|
void technicalIncident();
|
2020-10-06 13:58:42 +02:00
|
|
|
ScStw::StatusCode setTimerDisabled(ScStwTimer* timer, bool disabled);
|
2020-04-11 23:41:34 +02:00
|
|
|
|
2020-10-03 17:45:54 +02:00
|
|
|
virtual void refreshCompetitionMode();
|
|
|
|
|
|
|
|
double getSoundVolume();
|
|
|
|
ScStwSoundPlayer::StartSound getSoundForState(ScStwRace::RaceState state);
|
|
|
|
bool getSoundEnabledSetting(ScStwSoundPlayer::StartSound sound);
|
|
|
|
int getSoundDelaySetting(ScStwSoundPlayer::StartSound sound);
|
|
|
|
|
|
|
|
|
2020-10-01 01:54:39 +02:00
|
|
|
bool isStarting();
|
2020-10-03 11:10:15 +02:00
|
|
|
virtual bool getIsReadyForNextState();
|
2020-10-02 19:53:07 +02:00
|
|
|
void handleTimerReadyStateChange(ScStwTimer::ReadyState readyState);
|
2020-10-01 01:54:39 +02:00
|
|
|
|
2020-04-11 23:41:34 +02:00
|
|
|
signals:
|
|
|
|
void startTimers();
|
|
|
|
void stopTimers(int type);
|
|
|
|
void resetTimers();
|
|
|
|
void stateChanged(RaceState state);
|
2020-10-02 14:16:24 +02:00
|
|
|
void currentStartDelayChanged();
|
2020-04-17 19:57:00 +02:00
|
|
|
void timersChanged();
|
2020-10-02 19:56:08 +02:00
|
|
|
void isReadyForNextStateChanged();
|
2020-10-02 19:53:07 +02:00
|
|
|
void detailsChanged();
|
2020-10-03 11:44:56 +02:00
|
|
|
void competitionModeChanged();
|
|
|
|
void readySoundEnabledChanged();
|
2020-10-09 15:18:56 +02:00
|
|
|
void settingsChanged();
|
|
|
|
void autoRefreshTimerTextChanged();
|
2020-04-11 23:41:34 +02:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // SCSTWRACE_H
|