File indexing completed on 2024-04-14 03:47:51

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007-2008 David Roberts <dvdr18@gmail.com>
0004 // SPDX-FileCopyrightText: 2010 Harshit Jain <hjain.itbhu@gmail.com>
0005 //
0006 
0007 #include "MarbleClock.h"
0008 #include "MarbleDebug.h"
0009 
0010 #include <QDateTime>
0011 #include <QTimer>
0012 
0013 namespace Marble {
0014 
0015 class MarbleClockPrivate
0016 {
0017 public:
0018     MarbleClock* q;
0019     int        m_speed;
0020     QTimer     m_timer;
0021     QDateTime  m_datetime;        // stores the UTC time
0022     QDateTime  m_lasttime;
0023     int        m_timezoneInSec;
0024     int        m_updateInterval;
0025 
0026     explicit MarbleClockPrivate( MarbleClock* parent );
0027 
0028     void timerTimeout();
0029 };
0030 
0031 MarbleClockPrivate::MarbleClockPrivate( MarbleClock* parent ) :
0032     q( parent ),
0033     m_speed( 1 ),
0034     m_datetime( QDateTime::currentDateTimeUtc() ),
0035     m_lasttime( QDateTime::currentDateTimeUtc() ),
0036     m_timezoneInSec( 0 ),
0037     m_updateInterval( 60 )
0038 {
0039     // nothing to do
0040 }
0041 
0042 void MarbleClockPrivate::timerTimeout()
0043 {
0044     // calculate real period elapsed since last call
0045     QDateTime curenttime( QDateTime::currentDateTimeUtc() );
0046     int msecdelta = m_lasttime.msecsTo( curenttime );
0047     m_lasttime = curenttime;
0048 
0049     // update m_datetime at m_speed pace
0050     m_datetime = m_datetime.addMSecs( msecdelta * m_speed );
0051 
0052     // trigger round minute update (at m_speed pace)
0053     emit q->timeChanged();
0054 
0055     // sleeptime is the time to sleep until next round minute, at m_speed pace
0056     int sleeptime = ( m_updateInterval * 1000 - (qreal)(m_datetime.time().msec() + m_datetime.time().second() * 1000 ) ) / m_speed;
0057     if ( sleeptime < 1000 ) {
0058         // don't trigger more often than 1s
0059         sleeptime = 1000;
0060     }
0061     m_timer.start( sleeptime );
0062 
0063     //mDebug() << "MarbleClock: will sleep for " << sleeptime;
0064 }
0065 
0066 MarbleClock::MarbleClock( QObject* parent )
0067     : QObject( parent ), d( new MarbleClockPrivate( this ) )
0068 
0069 {
0070     connect( &d->m_timer, SIGNAL(timeout()),
0071              this,    SLOT(timerTimeout()) );
0072     d->timerTimeout();
0073 }
0074 
0075 
0076 MarbleClock::~MarbleClock()
0077 {
0078     delete d;
0079 }
0080 
0081 qreal MarbleClock::dayFraction() const
0082 {
0083     qreal fraction = d->m_datetime.time().second();
0084     fraction = fraction/60.0 + d->m_datetime.time().minute();
0085     fraction = fraction/60.0 + d->m_datetime.time().hour();
0086     fraction = fraction/24.0;
0087     return fraction;
0088 }
0089 
0090 void MarbleClock::setDateTime( const QDateTime& datetime )
0091 {
0092     d->m_datetime = datetime;
0093     d->timerTimeout();
0094 }
0095 
0096 QDateTime MarbleClock::dateTime() const
0097 {
0098     return d->m_datetime;
0099 }
0100 
0101 void MarbleClock::setUpdateInterval( int seconds )
0102 {
0103     d->m_updateInterval = seconds;
0104     emit updateIntervalChanged( seconds );
0105 }
0106 
0107 int MarbleClock::updateInterval() const
0108 {
0109     return d->m_updateInterval;
0110 }
0111 
0112 int MarbleClock::speed() const
0113 {
0114     return d->m_speed;
0115 }
0116 
0117 void MarbleClock::setSpeed( int speed )
0118 {
0119     d->m_speed = speed;
0120     d->timerTimeout();
0121 }
0122 
0123 int MarbleClock::timezone() const
0124 {
0125     return d->m_timezoneInSec;
0126 }
0127 
0128 void MarbleClock::setTimezone( int timezoneInSec )
0129 {
0130     d->m_timezoneInSec = timezoneInSec;
0131 }
0132 
0133 }
0134 
0135 #include "moc_MarbleClock.cpp"