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 };