LCOV - code coverage report
Current view: top level - Core/Scripting - OOScriptTimer.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 6 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOScriptTimer.m
       4             : 
       5             : 
       6             : Oolite
       7             : Copyright (C) 2004-2013 Giles C Williams and contributors
       8             : 
       9             : This program is free software; you can redistribute it and/or
      10             : modify it under the terms of the GNU General Public License
      11             : as published by the Free Software Foundation; either version 2
      12             : of the License, or (at your option) any later version.
      13             : 
      14             : This program is distributed in the hope that it will be useful,
      15             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             : GNU General Public License for more details.
      18             : 
      19             : You should have received a copy of the GNU General Public License
      20             : along with this program; if not, write to the Free Software
      21             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      22             : MA 02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : #import "OOScriptTimer.h"
      27             : #import "Universe.h"
      28             : #import "OOLogging.h"
      29             : #import "OOPriorityQueue.h"
      30             : 
      31             : 
      32           0 : static OOPriorityQueue  *sTimers;
      33             : 
      34             : // During an update, new timers must be deferred to avoid an infinite loop.
      35           0 : static BOOL                             sUpdating;
      36           0 : static NSMutableArray   *sDeferredTimers;
      37             : 
      38             : 
      39             : @implementation OOScriptTimer
      40             : 
      41             : - (id) initWithNextTime:(OOTimeAbsolute)nextTime
      42             :                            interval:(OOTimeDelta)interval
      43             : {
      44             :         OOTimeAbsolute                  now;
      45             :         
      46             :         if ((self = [super init]))
      47             :         {
      48             :                 if (interval <= 0.0)  interval = -1.0;
      49             :                 
      50             :                 now = [UNIVERSE getTime];
      51             :                 if (nextTime < 0.0)  nextTime = now + interval;
      52             :                 if (nextTime < now && interval < 0)
      53             :                 {
      54             :                         // Negative or old nextTime and negative interval = meaningless.
      55             :                         [self release];
      56             :                         self = nil;
      57             :                 }
      58             :                 else
      59             :                 {
      60             :                         _nextTime = nextTime;
      61             :                         _interval = interval;
      62             :                         _hasBeenRun = NO;
      63             :                 }
      64             :         }
      65             :         
      66             :         return self;
      67             : }
      68             : 
      69             :         // Sets nextTime to current time + delay.
      70             : - (id) initOneShotTimerWithDelay:(OOTimeDelta)delay
      71             : {
      72             :         return [self initWithNextTime:[UNIVERSE getTime] + delay interval:-1.0];
      73             : }
      74             : 
      75             : 
      76           0 : - (void) dealloc
      77             : {
      78             :         if (_isScheduled)  [self unscheduleTimer];
      79             :         
      80             :         [super dealloc];
      81             : }
      82             : 
      83             : 
      84           0 : - (NSString *) descriptionComponents
      85             : {
      86             :         NSString                                        *intervalDesc = nil;
      87             :         
      88             :         if (_interval <= 0.0)  intervalDesc = @"one-shot";
      89             :         else  intervalDesc = [NSString stringWithFormat:@"interval: %g", _interval];
      90             :                 
      91             :         return [NSString stringWithFormat:@"nextTime: %g, %@, %srunning", _nextTime, intervalDesc, _isScheduled ? "" : "not "];
      92             : }
      93             : 
      94             : 
      95             : - (OOTimeAbsolute)nextTime
      96             : {
      97             :         return _nextTime;
      98             : }
      99             : 
     100             : 
     101             : - (BOOL)setNextTime:(OOTimeAbsolute)nextTime
     102             : {
     103             :         if (_isScheduled)  return NO;
     104             :         
     105             :         _nextTime = nextTime;
     106             :         return YES;
     107             : }
     108             : 
     109             : 
     110             : - (OOTimeDelta)interval
     111             : {
     112             :         return _interval;
     113             : }
     114             : 
     115             : 
     116             : - (void)setInterval:(OOTimeDelta)interval
     117             : {
     118             :         if (interval <= 0.0)  interval = -1.0;
     119             :         _interval = interval;
     120             : }
     121             : 
     122             : 
     123             : - (void) timerFired
     124             : {
     125             :         OOLogGenericSubclassResponsibility();
     126             : }
     127             : 
     128             : 
     129             : - (BOOL) scheduleTimer
     130             : {
     131             :         if (_isScheduled)  return YES;
     132             :         if (![self isValidForScheduling])  return NO;
     133             :         
     134             :         if (EXPECT(!sUpdating))
     135             :         {
     136             :                 if (EXPECT_NOT(sTimers == nil))  sTimers = [[OOPriorityQueue alloc] initWithComparator:@selector(compareByNextFireTime:)];
     137             :                 [sTimers addObject:self];
     138             :         }
     139             :         else
     140             :         {
     141             :                 if (sDeferredTimers == nil)  sDeferredTimers = [[NSMutableArray alloc] init];
     142             :                 [sDeferredTimers addObject:self];
     143             :         }
     144             :         
     145             :         _isScheduled = YES;
     146             :         return YES;
     147             : }
     148             : 
     149             : 
     150             : - (void) unscheduleTimer
     151             : {
     152             :         [sTimers removeExactObject:self];
     153             :         _isScheduled = NO;
     154             :         _hasBeenRun = NO;
     155             : }
     156             : 
     157             : 
     158             : - (BOOL) isScheduled
     159             : {
     160             :         return _isScheduled;
     161             : }
     162             : 
     163             : 
     164             : + (void) updateTimers
     165             : {
     166             :         OOScriptTimer           *timer = nil;
     167             :         OOTimeAbsolute          now;
     168             :         
     169             :         sUpdating = YES;
     170             :         
     171             :         now = [UNIVERSE getTime];
     172             :         for (;;)
     173             :         {
     174             :                 timer = [sTimers peekAtNextObject];
     175             :                 if (timer == nil || now < [timer nextTime])  break;
     176             :                 
     177             :                 [sTimers removeNextObject];
     178             :                 
     179             :                 // Must fire before rescheduling so that the timer callback can stop itself. -- Ahruman 2011-01-01
     180             :                 [timer timerFired];
     181             :                 
     182             :                 timer->_hasBeenRun = YES;
     183             :                 
     184             :                 if (timer->_isScheduled)
     185             :                 {
     186             :                         timer->_isScheduled = NO;
     187             :                         [timer scheduleTimer];
     188             :                 }
     189             :         }
     190             :         
     191             :         if (sDeferredTimers != nil)
     192             :         {
     193             :                 [sTimers addObjects:sDeferredTimers];
     194             :                 DESTROY(sDeferredTimers);
     195             :         }
     196             :         
     197             :         sUpdating = NO;
     198             : }
     199             : 
     200             : 
     201             : + (void) noteGameReset
     202             : {
     203             :         NSArray                         *timers = nil;
     204             :         NSEnumerator            *timerEnum = nil;
     205             :         OOScriptTimer           *timer = nil;
     206             :         
     207             :         // Intermediate array is required so we don't get stuck in an endless loop over reinserted timers. Note that -sortedObjects also clears the queue!
     208             :         timers = [sTimers sortedObjects];
     209             :         for (timerEnum = [timers objectEnumerator]; (timer = [timerEnum nextObject]); )
     210             :         {
     211             :                 timer->_isScheduled = NO;
     212             :         }
     213             : }
     214             : 
     215             : 
     216             : - (BOOL) isValidForScheduling
     217             : {
     218             :         OOTimeAbsolute          now;
     219             :         double                          scaled;
     220             :         
     221             :         now = [UNIVERSE getTime];
     222             :         if (_nextTime <= now)
     223             :         {
     224             :                 if (_interval <= 0.0 && _hasBeenRun)  return NO;     // One-shot timer which has expired
     225             :                 
     226             :                 // Move _nextTime to the closest future time that's a multiple of _interval
     227             :                 scaled = (now - _nextTime) / _interval;
     228             :                 scaled = ceil(scaled);
     229             :                 _nextTime += scaled * _interval;
     230             :                 if (_nextTime <= now && _hasBeenRun) 
     231             :                 {
     232             :                         // Should only happen if _nextTime is exactly equal to now after previous stuff
     233             :                         _nextTime += _interval;
     234             :                 }
     235             :         }
     236             :         
     237             :         return YES;
     238             : }
     239             : 
     240             : - (NSComparisonResult) compareByNextFireTime:(OOScriptTimer *)other
     241             : {
     242             :         OOTimeAbsolute          otherTime = -INFINITY;
     243             :         
     244             :         @try
     245             :         {
     246             :                 if (other != nil)  otherTime = [other nextTime];
     247             :         }
     248             :         @catch (NSException *exception)
     249             :         {
     250             :                 OOLog(kOOLogException, @"\n\n***** Ignoring Timer Exception: %@ : %@ *****\n\n",[exception name], [exception reason]);
     251             :         }
     252             :         
     253             :         if (_nextTime < otherTime) return NSOrderedAscending;
     254             :         else if (_nextTime > otherTime) return NSOrderedDescending;
     255             :         else  return NSOrderedSame;
     256             : }
     257             : 
     258             : @end

Generated by: LCOV version 1.14