File indexing completed on 2024-04-21 14:46:48

0001 /*
0002     SPDX-FileCopyrightText: 2002 Mark Hollomon <mhh@mindspring.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "simclock.h"
0008 
0009 #ifndef KSTARS_LITE
0010 #include "kstars.h"
0011 #include "simclockadaptor.h"
0012 #endif
0013 
0014 #include <kstars_debug.h>
0015 
0016 int SimClock::TimerInterval = 100; //msec
0017 
0018 SimClock::SimClock(QObject *parent, const KStarsDateTime &when) : QObject(parent), m_InternalTimer(this)
0019 {
0020 #ifndef KSTARS_LITE
0021     new SimClockAdaptor(this);
0022     QDBusConnection::sessionBus().registerObject("/KStars/SimClock", this);
0023 #endif
0024     if (!when.isValid())
0025         m_InternalTimer.stop();
0026     setUTC(when);
0027     m_JulianMark = m_UTC.djd();
0028 
0029     QObject::connect(&m_InternalTimer, SIGNAL(timeout()), this, SLOT(tick()));
0030 }
0031 
0032 void SimClock::tick()
0033 {
0034     if (!m_ManualMode) //only tick if ManualMode is false
0035     {
0036         long mselapsed = m_SystemMark.elapsed();
0037         if (mselapsed < m_LastElapsed)
0038         {
0039             // The sysmark timer has wrapped after 24 hours back to 0 ms.
0040             // Reset sysmark and julianmark
0041             m_JulianMark = m_UTC.djd();
0042             m_SystemMark.start();
0043             m_LastElapsed = 0;
0044         }
0045         else
0046         {
0047             m_LastElapsed = mselapsed;
0048         }
0049 
0050         long double scaledsec = static_cast<long double>(mselapsed) * static_cast<long double>(m_Scale) / 1000.0;
0051         m_UTC.setDJD(m_JulianMark + scaledsec / (24. * 3600.));
0052 
0053         //      qDebug() << Q_FUNC_INFO << "tick() : JD = " << QLocale().toString( UTC.djd(), 7 ) <<
0054         //          " mselapsed = " << mselapsed << " scale = " << Scale <<
0055         //          "  scaledsec = " << double(scaledsec);
0056 
0057         emit timeAdvanced();
0058     }
0059 }
0060 
0061 void SimClock::setManualMode(bool on)
0062 {
0063     if (on)
0064     {
0065         //Turn on manual ticking.
0066         m_ManualActive = m_InternalTimer.isActive();
0067         m_InternalTimer.stop();
0068     }
0069     else
0070     {
0071         //Turn off manual ticking.  If the Manual clock was active, start the timer.
0072         if (isActive())
0073         {
0074             m_SystemMark.start();
0075             m_JulianMark  = m_UTC.djd();
0076             m_LastElapsed = 0;
0077             m_InternalTimer.start(TimerInterval);
0078         }
0079     }
0080     m_ManualMode = on;
0081 }
0082 
0083 void SimClock::manualTick(bool force, bool backward)
0084 {
0085     if (force || (m_ManualMode && m_ManualActive))
0086     {
0087         //The single shot timer is needed because otherwise the animation is happening so frequently
0088         //that the kstars interface becomes too unresponsive.
0089         //QTimer::singleShot(1, [this,backward] { setUTC(UTC.addSecs(static_cast<long double>Scale * (backward ? -1 : 1))); });
0090         setUTC(m_UTC.addSecs(static_cast<long double>(m_Scale) * (backward ? -1 : 1)));
0091     }
0092     else if (!m_ManualMode)
0093         tick();
0094 }
0095 
0096 bool SimClock::isActive()
0097 {
0098     if (m_ManualMode)
0099         return m_ManualActive;
0100     else
0101         return m_InternalTimer.isActive();
0102 }
0103 
0104 void SimClock::stop()
0105 {
0106     if (m_ManualMode && m_ManualActive)
0107     {
0108         m_ManualActive = false;
0109         emit clockToggled(true);
0110     }
0111 
0112     if (!m_ManualMode && m_InternalTimer.isActive())
0113     {
0114         qCDebug(KSTARS) << "Stopping the timer";
0115         m_InternalTimer.stop();
0116         emit clockToggled(true);
0117     }
0118 }
0119 
0120 void SimClock::start()
0121 {
0122     if (m_ManualMode && !m_ManualActive)
0123     {
0124         m_ManualActive = true;
0125         m_SystemMark.start();
0126         m_JulianMark  = m_UTC.djd();
0127         m_LastElapsed = 0;
0128         emit clockToggled(false);
0129         //emit timeChanged() in order to restart calls to updateTime()
0130         emit timeChanged();
0131     }
0132     else if (!m_ManualMode && !m_InternalTimer.isActive())
0133     {
0134         qCDebug(KSTARS) << "Starting the timer";
0135         m_SystemMark.start();
0136         m_JulianMark  = m_UTC.djd();
0137         m_LastElapsed = 0;
0138         m_InternalTimer.start(TimerInterval);
0139         emit clockToggled(false);
0140     }
0141 }
0142 
0143 void SimClock::setUTC(const KStarsDateTime &newtime)
0144 {
0145     //DEBUG
0146     //qDebug() << Q_FUNC_INFO << newtime.toString();
0147     //qDebug() << Q_FUNC_INFO << "is dateTime valid? " << newtime.isValid();
0148 
0149     if (newtime.isValid())
0150     {
0151         m_UTC = newtime;
0152         if (m_InternalTimer.isActive())
0153         {
0154             m_JulianMark = m_UTC.djd();
0155             m_SystemMark.start();
0156             m_LastElapsed = 0;
0157         }
0158 
0159         // N.B. Too much log spam when in manual mode
0160         //qCInfo(KSTARS) << QString("Setting clock:  UTC: %1  JD: %2").arg(UTC.toString(), QLocale().toString((double)UTC.djd(), 'f', 2));
0161         emit timeChanged();
0162     }
0163     else
0164     {
0165         qCWarning(KSTARS) << "Cannot set SimClock:  Invalid Date/Time.";
0166     }
0167 }
0168 
0169 void SimClock::setClockScale(double scale)
0170 {
0171     if (m_Scale != scale)
0172     {
0173         qCInfo(KSTARS) << "New clock scale: " << scale << " sec";
0174         emit scaleChanged(scale);
0175         m_Scale = scale;
0176         if (m_InternalTimer.isActive())
0177         {
0178             m_JulianMark = m_UTC.djd();
0179             m_SystemMark.start();
0180             m_LastElapsed = 0;
0181         }
0182     }
0183 }