Inefficient stopwatch

Hi All,

I have been playing around with creating a simple stopwatch counter that displays time counting up when the screen is touched.  When subsequent touches are made the counter is paused/un-paused.

One problem I am finding is that the timer call that starts the stopwatch and the display text continues to “play” even when the stopwatch is paused.  Whilst the code below does work and start, pause and un-pause the stopwatch every time a touch is made I think a new timer.performWithDelay call is invoked each time??

In any case the performance of the code appears to degrade as more touch events occur.  

Any advice or tips on how to improve my code below so that this behaviour isn’t occurring?

Hope this makes sense

function MilliSecondsToClock(sMilliSeconds)     local ms = sMilliSeconds     if ms == 0 then         return "00:00:00:000"     else         nHours = string.format("%02.f", math.floor(ms/(1000\*60\*60)))         nMins  = string.format("%02.f", math.mod(ms,(1000\*60\*60))/(1000\*60))          nSecs  = string.format("%02.f", math.mod(math.mod(ms,(1000\*60\*60)),(1000\*60))/1000)         nMSecs = string.format("%03.f", math.mod(math.mod(math.mod(ms,(1000\*60\*60)),(1000\*60)),1000))          return nHours..":"..nMins..":"..nSecs..":"..nMSecs     end end local stopwatch = require "stopwatch" local timeKeep = stopwatch.new() timeKeep:pause() local timerRunning = 0 function startTimer( event )     if event.phase == "began" then         print ( "startTimer()" )         function fn\_counter()             print ("fn\_counter()")             local milliseconds = timeKeep:getElapsed()             local time = MilliSecondsToClock(milliseconds)             local myText = display.newText( time, 480, 100, native.systemFont, 50 )             function removeText()                 display.remove( myText )             end             timer.performWithDelay( 100, removeText, 1)             myText:setFillColor( 1,1,1 )         end         print ("timerRunning: " .. timerRunning)         if timerRunning == 0 then             print ("timerRunning == 0")             timerRunning = 1             timeKeep:resume()             timer.performWithDelay(100, fn\_counter, 0)         elseif timerRunning == 1 then             print ("timerRunning == 1")             timerRunning = 0             timeKeep:pause()         end     end  end Runtime:addEventListener("touch",startTimer)  

You never stop the (corona-)timer when you pause the stopwatch … timer.performWithDelay( …, 0 ) means “loop forever”.  You probably need to catch the timer-handle and then cancel it when you want to pause the timer:

-- you may need a global timer-variable mainTimer = timer.performWithDelay(100, fn\_counter, 0) ... elseif timerRunning == 1 then timerRunning = 0 timeKeep:pause() timer.cancel( mainTimer ) end

The next thing that pops out at me is that the way you remove the text boxes may not be quite right (though I’m a bit hazy on this myself).  

In addition to removing the text object, you may also need to set myText=nil to ensure that the garbage collector can harvest it.  If you’re creating display objects at 10-per-second, that could potentially give you some performance issues.  

You never stop the (corona-)timer when you pause the stopwatch … timer.performWithDelay( …, 0 ) means “loop forever”.  You probably need to catch the timer-handle and then cancel it when you want to pause the timer:

-- you may need a global timer-variable mainTimer = timer.performWithDelay(100, fn\_counter, 0) ... elseif timerRunning == 1 then timerRunning = 0 timeKeep:pause() timer.cancel( mainTimer ) end

The next thing that pops out at me is that the way you remove the text boxes may not be quite right (though I’m a bit hazy on this myself).  

In addition to removing the text object, you may also need to set myText=nil to ensure that the garbage collector can harvest it.  If you’re creating display objects at 10-per-second, that could potentially give you some performance issues.