A couple of days ago I had a few extra minutes in the morning to work on my app. I thought I would quickly add the option to pause the timer. This sounded simple enough and I figured I could add this feature in 15 or 20 minutes. Well, about three hours later I had it more or less figured out. You just never know where app development will take you.
The concept sounds simple enough - just stop everything with one click and restart it all with another click. But, this proved to be a more thornier challenge than it would seem at first glance. It stems from the fact that I'm using LiveCode's function the seconds as the way to keep the timer and the intervals accurate. (I explained how the seconds works in LiveCode in my previous blog posting. I recommend reading that first before continuing here.)
Here's a short explanation:
When the timer begins it saves the current time (in seconds) in a variable. For simplicity sake, let's just say that the seconds is equal to 0. The app then continually checks the current time and puts those seconds into the display. When the Stop button is pressed, the current time at that moment is saved into another variable and the timer is stopped. Of course, the seconds - time, in other words - just keeps going. When the Start button is pressed to start the timer up again I can't just restart the timer based the seconds at that moment because the time elapsed includes the time that the timer was paused. So, I have to subtract the paused time from the total time and only show the "running" time in the display. Here's the solution I programmed into the app:
0 seconds: Start the timer
50 seconds: Pause the timer. At this point, 0:50 remains on the display.
150 seconds: Start the timer back up. 150-50 is 100 seconds. So the display needs to show the following:
Current Time (150) - Original Starting Time (0) - Total Time Paused (100) = Total timer seconds to be displayed
And, every time the user pressed the Stop button, the total time paused must be increased accordingly.
All I can say is that I couldn't get it to work for about three hours. Somewhere my logic was failing me. In the end, I think the problem was that I had this algorithm sitting in the wrong place, namely inside the LloydStopWatch procedure I explained in my previous post. After I moved it and a few more tweaks, things seemed to work, more or less. I say "more or less" because there is still a small bug. Somehow one second is sometimes added to the total time elapsed. The problem is minor, but annoying. Here's what can happen. Imagine the timer with two intervals, each two seconds apart. The first interval is signaled with a bell and the second with chimes. So, the pattern is a timer going off every two seconds, first with a bell and then with chimes. So, an alert should be given only when an even number appears on the display. However, sometimes when pause is pressed, the alert sounds moves to odd numbers instead, but at two second intervals. It seems to resemble a kind of "rounding" error, but I can't find the source. So, after those three hours, I decided to just "let it go."
Displaying the Time Correctly
I made one other improvement to the app, namely showing the timer not just in seconds, but in minutes and seconds using the conventional display of Minutes:Seconds. This was a fun challenge to program. So, consider that a total of 147 seconds have gone by. What should the display read? A quick mental calculation results in 2 minutes and 27 seconds, or 02:27. That same mental calculation is shown in this code:
1: put trunc(varTimeElapsed/60) into varDisplayMinutes 2: put (varTimeElapsed)-(varDisplayMinutes*60) into varDisplaySeconds 3: if the length of varDisplaySeconds < 2 then put "0"&varDisplaySeconds into varDisplaySeconds 4: put varDisplayMinutes&":"&varDisplaySeconds into line 1 of field "my time"
In line 1, we divide the total seconds elapsed (varTimeElapsed) by 60. Dividing 147 by 60 gives you 2.45. Well, we just care first about the number of minutes. The function trunc truncates, or chops off, any decimal that remains. So, we are left with just two. That goes into the variable varDisplayMinutes.
Now we have to figure out the remaining number of seconds. All we need to do is take the total seconds elapsed (again, varTimeElapsed) and subtract from it the number minutes we just calculated. Of course, we have to convert those minutes back into seconds first (varDisplayMinutes*60). The result is line 2: 147-120 = 27. We put the 27 into the variable varDisplaySeconds.
Lines 4 pretties everything up before displaying the time elapsed in the field "my time." Using the concatenation symbol "&" we stitch together minutes, a colon in the middle, followed by the seconds.
Adding a Fourth Interval Option and Alert Sound Options
In my last blog post, I alluded to the fact that having at least four intervals is preferred. So, this version of the app added that as well. I also had some fun finding and adding a menu of alert sounds. I downloaded several sound effects using the .wav sound format from this web site:
Here's a screen shot of the current version of the app paused after 97 seconds:
One More Important Step to Go
The app works well enough for me to brush my teeth, except for one thing. I don't want to put my laptop on the bathroom sink. So, the obvious next step is to "go mobile." This will require quite a few changes to the app's interface, such as replacing all of the text input fields with selector wheels.
I also will need to move the app to my iPhone for testing. I am not looking forward to this. It will first require me to relearn how to create a "provisioning profile" in my Apple Developer Account using my iPhone's serial number and then relearning how to get the app from my computer to the iPhone. I've done it before and I'm sure I can do it again. But, it's been a few years and my memory of doing it isn't very pleasant.