1 /*
2 SPDX-FileCopyrightText: 2002 Mark Hollomon <mhh@mindspring.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "simclock.h"
8
9 #ifndef KSTARS_LITE
10 #include "kstars.h"
11 #include "simclockadaptor.h"
12 #endif
13
14 #include <kstars_debug.h>
15
16 int SimClock::TimerInterval = 100; //msec
17
SimClock(QObject * parent,const KStarsDateTime & when)18 SimClock::SimClock(QObject *parent, const KStarsDateTime &when) : QObject(parent), tmr(this)
19 {
20 #ifndef KSTARS_LITE
21 new SimClockAdaptor(this);
22 QDBusConnection::sessionBus().registerObject("/KStars/SimClock", this);
23 #endif
24 if (!when.isValid())
25 tmr.stop();
26 setUTC(when);
27 julianmark = UTC.djd();
28
29 QObject::connect(&tmr, SIGNAL(timeout()), this, SLOT(tick()));
30 }
31
tick()32 void SimClock::tick()
33 {
34 if (!ManualMode) //only tick if ManualMode is false
35 {
36 long mselapsed = sysmark.elapsed();
37 if (mselapsed < lastelapsed)
38 {
39 // The sysmark timer has wrapped after 24 hours back to 0 ms.
40 // Reset sysmark and julianmark
41 julianmark = UTC.djd();
42 sysmark.start();
43 lastelapsed = 0;
44 }
45 else
46 {
47 lastelapsed = mselapsed;
48 }
49
50 long double scaledsec = static_cast<long double>(mselapsed) * static_cast<long double>(Scale) / 1000.0;
51 UTC.setDJD(julianmark + scaledsec / (24. * 3600.));
52
53 // qDebug() << "tick() : JD = " << QLocale().toString( UTC.djd(), 7 ) <<
54 // " mselapsed = " << mselapsed << " scale = " << Scale <<
55 // " scaledsec = " << double(scaledsec);
56
57 emit timeAdvanced();
58 }
59 }
60
setManualMode(bool on)61 void SimClock::setManualMode(bool on)
62 {
63 if (on)
64 {
65 //Turn on manual ticking.
66 ManualActive = tmr.isActive();
67 tmr.stop();
68 }
69 else
70 {
71 //Turn off manual ticking. If the Manual clock was active, start the timer.
72 if (isActive())
73 {
74 sysmark.start();
75 julianmark = UTC.djd();
76 lastelapsed = 0;
77 tmr.start(TimerInterval);
78 }
79 }
80 ManualMode = on;
81 }
82
manualTick(bool force,bool backward)83 void SimClock::manualTick(bool force, bool backward)
84 {
85 if (force || (ManualMode && ManualActive))
86 {
87 //The single shot timer is needed because otherwise the animation is happening so frequently
88 //that the kstars interface becomes too unresponsive.
89 //QTimer::singleShot(1, [this,backward] { setUTC(UTC.addSecs(static_cast<long double>Scale * (backward ? -1 : 1))); });
90 setUTC(UTC.addSecs(static_cast<long double>(Scale) * (backward ? -1 : 1)));
91 }
92 else if (!ManualMode)
93 tick();
94 }
95
isActive()96 bool SimClock::isActive()
97 {
98 if (ManualMode)
99 return ManualActive;
100 else
101 return tmr.isActive();
102 }
103
stop()104 void SimClock::stop()
105 {
106 if (ManualMode && ManualActive)
107 {
108 ManualActive = false;
109 emit clockToggled(true);
110 }
111
112 if (!ManualMode && tmr.isActive())
113 {
114 qCDebug(KSTARS) << "Stopping the timer";
115 tmr.stop();
116 emit clockToggled(true);
117 }
118 }
119
start()120 void SimClock::start()
121 {
122 if (ManualMode && !ManualActive)
123 {
124 ManualActive = true;
125 sysmark.start();
126 julianmark = UTC.djd();
127 lastelapsed = 0;
128 emit clockToggled(false);
129 //emit timeChanged() in order to restart calls to updateTime()
130 emit timeChanged();
131 }
132 else if (!ManualMode && !tmr.isActive())
133 {
134 qCDebug(KSTARS) << "Starting the timer";
135 sysmark.start();
136 julianmark = UTC.djd();
137 lastelapsed = 0;
138 tmr.start(TimerInterval);
139 emit clockToggled(false);
140 }
141 }
142
setUTC(const KStarsDateTime & newtime)143 void SimClock::setUTC(const KStarsDateTime &newtime)
144 {
145 //DEBUG
146 //qDebug() << newtime.toString();
147 //qDebug() << "is dateTime valid? " << newtime.isValid();
148
149 if (newtime.isValid())
150 {
151 UTC = newtime;
152 if (tmr.isActive())
153 {
154 julianmark = UTC.djd();
155 sysmark.start();
156 lastelapsed = 0;
157 }
158
159 // N.B. Too much log spam when in manual mode
160 //qCInfo(KSTARS) << QString("Setting clock: UTC: %1 JD: %2").arg(UTC.toString(), QLocale().toString((double)UTC.djd(), 'f', 2));
161 emit timeChanged();
162 }
163 else
164 {
165 qCWarning(KSTARS) << "Cannot set SimClock: Invalid Date/Time.";
166 }
167 }
168
setClockScale(float s)169 void SimClock::setClockScale(float s)
170 {
171 if (Scale != s)
172 {
173 qCInfo(KSTARS) << "New clock scale: " << s << " sec";
174 emit scaleChanged(s);
175 Scale = s;
176 if (tmr.isActive())
177 {
178 julianmark = UTC.djd();
179 sysmark.start();
180 lastelapsed = 0;
181 }
182 }
183 }
184