File indexing completed on 2024-04-14 14:11:32

0001 /*
0002     SPDX-FileCopyrightText: 2002 Mark Hollomon <mhh@mindspring.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "kstarsdatetime.h"
0010 
0011 #include <QTime>
0012 #include <QElapsedTimer>
0013 #include <QTimer>
0014 #include <qtdbusglobal.h>
0015 
0016 /** @class SimClock
0017     *@short kstars simulation clock
0018     *@author Mark Hollomon
0019     *@version 1.0
0020     */
0021 
0022 class SimClock : public QObject
0023 {
0024         Q_OBJECT
0025         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.SimClock")
0026     public:
0027         /**
0028              * Constructor
0029              * @param parent parent object for the clock
0030              * @param when the date/time to which the SimClock should be initialized in UTC
0031              */
0032         explicit SimClock(QObject *parent = nullptr, const KStarsDateTime &when = KStarsDateTime::currentDateTimeUtc());
0033 
0034         /** @return const reference to the current simulation Universal Time. */
0035         const KStarsDateTime &utc() const
0036         {
0037             return m_UTC;
0038         }
0039 
0040         /** Whether the clock is active or not is a bit complicated by the
0041                 *introduction of "manual mode".  In manual mode, SimClock's internal timer
0042                 *is stopped, because the clock is ticked manually when the current update
0043                 *has finished.  So, if ManualMode is true, then isActive() checks
0044                 *whether ManualActive is true.  Otherwise, it checks whether the timer is
0045                 *running.
0046                 *@returns true if the Simulation clock is actively running.
0047                 */
0048         Q_INVOKABLE bool isActive();
0049 
0050         /** @returns the current timestep setting */
0051         double scale() const
0052         {
0053             return m_Scale;
0054         }
0055 
0056         /** Manual Mode is a new (04/2002) addition to the SimClock.  It is
0057                 *intended to be activated for large timesteps, when we want each frame
0058                 *drawn to the screen to be precisely Scale seconds later than the
0059                 *previous frame.  (i.e., if the timescale is 1 year, then each successive
0060                 *frame should be 1 year later than the previous frame).  ManualMode
0061                 *accomplishes this by stopping the internal timer and allowing the clock
0062                 *to be advanced manually (the manualTick() slot is called at the end of each
0063                 *KStars::updateTime()).
0064                 *@returns whether Manual Mode is active.
0065                 */
0066         bool isManualMode() const
0067         {
0068             return m_ManualMode;
0069         }
0070 
0071         /**Sets Manual Mode on/off according to the bool argument. */
0072         void setManualMode(bool on = true);
0073 
0074     public Q_SLOTS:
0075 #ifndef KSTARS_LITE
0076         /** DBUS function to stop the SimClock. */
0077         Q_SCRIPTABLE Q_NOREPLY void stop();
0078 
0079         /** DBUS function to start the SimClock. */
0080         Q_SCRIPTABLE Q_NOREPLY void start();
0081 
0082         /** DBUS function to set the time of the SimClock. */
0083         Q_SCRIPTABLE Q_NOREPLY void setUTC(const KStarsDateTime &newtime);
0084 
0085         /** DBUS function to set the current time of the SimClock. */
0086         Q_SCRIPTABLE Q_NOREPLY void setNow()
0087         {
0088             setUTC(KStarsDateTime::currentDateTimeUtc());
0089         }
0090 
0091         /** DBUS function to set scale of simclock. */
0092         /**
0093          * @brief setClockScale Set simulation clock scale per second.
0094          * @param scale Scale per second. 1 means normal scale, each 1 simulation
0095          * second equals 1 real second. Value less than one *slows* the simulation clock,
0096          * while values over 1 speeds it up. A scale of 0.5 makes the simulation clock ticks
0097          * once every 2 actual seconds (or half-ticks per one actual second),
0098          * while a value of 60 make the simulation clock ticks 60 simulation seconds (1 simulation minute)
0099          * for every 1 actual second.
0100          */
0101         Q_SCRIPTABLE Q_NOREPLY void setClockScale(double scale);
0102 #else
0103         // Define non-DBUS versions of functions above for use within KStarsLite
0104         /** Function to stop the SimClock. */
0105         void stop();
0106 
0107         /** Function to start the SimClock. */
0108         void start();
0109 
0110         /** Function to set the time of the SimClock. */
0111         void setUTC(const KStarsDateTime &newtime);
0112 
0113         /** Function to set scale of simclock. */
0114         void setClockScale(float s);
0115 #endif
0116 
0117         /** Respond to the QTimer::timeout signal */
0118         void tick();
0119 
0120         /** Equivalent of tick() for manual mode.
0121              * If ManualActive is true, add Scale seconds to the SimClock time.
0122              * (we may want to modify this slightly...e.g., the number of seconds in a
0123              * year is not constant (leap years), so it is better to increment the
0124              * year, instead of adding 31 million seconds.
0125              * set backward to true to reverse sign of Scale value
0126         */
0127 
0128         void manualTick(bool force = false, bool backward = false);
0129 
0130     signals:
0131         /** The time has changed (emitted by setUTC() ) */
0132         void timeChanged();
0133 
0134         /** The clock has ticked (emitted by tick() )*/
0135         void timeAdvanced();
0136 
0137         /** The timestep has changed*/
0138         void scaleChanged(float);
0139 
0140         /** This is an signal that is called on either clock start or
0141                 clock stop with an appropriate boolean argument. Required so
0142                 that we can bind it to KToggleAction::slotToggled(bool) */
0143         void clockToggled(bool);
0144 
0145     private:
0146         long double m_JulianMark { 0 };
0147         KStarsDateTime m_UTC;
0148         QTimer m_InternalTimer;
0149         double m_Scale { 1 };
0150         QElapsedTimer m_SystemMark;
0151         int m_LastElapsed { 0 };
0152         bool m_ManualMode { false };
0153         bool m_ManualActive { false };
0154 
0155         // used to generate names for dcop interfaces
0156         //static int idgen;
0157         // how often to update
0158         static int TimerInterval;
0159 
0160         // Disallow copying
0161         SimClock(const SimClock &);
0162         SimClock &operator=(const SimClock &);
0163 };