How to implement a stopwatch in Lua? - lua

How would you make a stopwatch in Lua?

I don't know Codea at all I'm afraid and you will most likely find that there are functions provided by that library for gettime and sleep. However as a pure Lua option (with the proviso that you use luasocket) the following code implements an example that could be built on.
socket = require('socket')
-- Define the stop watch
local start_time
function start()
-- Start the stop watch
start_time = socket.gettime() - 3800
end
function seconds_ellapsed()
-- Return the number of seconds since the stop watch was started
return socket.gettime() - start_time
end
-- As an example run the stop watch indefinately
start()
while true do
-- Get the time ellapsed and convert it to hours, minutes and seconds
ellapsed = seconds_ellapsed()
hours = math.floor(ellapsed / 3600)
minutes = math.floor((ellapsed - (hours * 3600)) / 60)
seconds = math.floor((ellapsed - (hours * 3600) - (minutes * 60)))
-- Print the time ellapsed to the command line
print(hours .. 'h', minutes .. 'm', seconds .. 's')
-- Wait a second between each update
socket.sleep(1)
end
You could look to use os.clock also but Lua has no builtin mechanism for setting the thread to sleep for a period (which was required for my example so I choose to use luasocket). There is a useful article on possible approaches for implementing sleep in lua here: http://lua-users.org/wiki/SleepFunction

Here is a very basic stopwatch, it starts/resets when the user taps the screen. This example shows elapsed minutes and seconds. If you want to count milliseconds, you can use ElapsedTime instead of os.time() and compute the number of hours, minutes etc. yourself instead of os.date(). Also, I don't have my iPad so there may be a bug.
function setup()
fontSize(20)
background(100, 120, 160)
fill(255)
toggle_timer()
end
function toggle_timer()
timer_on = not timer_on
if timer_on then
start = os.time()
end
end
function draw()
if timer_on then
text(os.date("%M:%S", os.difftime(os.time(), start)),
WIDTH / 2, HEIGHT / 2)
end
end
function touched(touch)
if touch.state == BEGAN then
toggle_timer()
end
end

Related

Can I make my Lua program to sleep for AROUND a day?

I want to make my mydicebot (by seuntje) Lua program sleep AROUND A DAY, after betting for a day... like
function sleep(n)
t = os.clock()
while os.clock() - t <= n do
-- nothing
end
end
function playsleep()
sec = math.random(80000,90000)
sleep(sec) -- around 86400 seconds
end
timestart = os.time()
dur = math.random(70000,80000)
function dobet()
if os.time() - timestart < math.random then
playsleep()
end
timestart = os.time() -- reset the time counter
end
but when I call the playsleep function in the dobet function
it ends up I cannot click anything in my program, cannot move another tab also
and the CPU is not sleeping either, even get busy
and sometimes it stucks even after 90000 seconds
-- THE QUESTIONS --
A. so can I make a function where the sleep is a real sleep?
B. can it sleep until 90000 seconds?
C. or what is the max number of sleep in seconds for the variable "sec" above?
Use the posix module to sleep:
posix = require("posix")
posix.sleep(86400)
But this will still block your program and you won't be able to click anything. You will need to provide more detail about your program in order to receive better advice.
Also os is there.
Why not...
do os.execute('$(type -path sleep) '..(3600*24)) end
...?

Remaining seconds until midnight

I'm trying to figure out a good way to get remaining seconds until midnight. I can think of some hacky solution with os.date() but is there a good function for this to go with os.time()?
local dt = os.date("*t")
local remaining_seconds = (dt.hour * -3600 - dt.min * 60 - dt.sec) % 86400
You can exploit the fact that the time and date library does date arithmetic:
dt=os.date("*t")
t0=os.time(dt)
dt.day=dt.day+1
dt.hour=0
dt.min=0
dt.sec=0
remaining_seconds=os.time(dt)-t0

I want lua function to run once

I'm quite new to lua scripting.. now i'm trying to code in game boss
local function SlitherEvents(event, creature, attacker, damage)
if(creature:GetHealthPct() <= 60) then
creature:SendUnitYell("Will punish you all",0)
creature:RegisterEvent(AirBurst, 1000, 0) -- 1 seconds
return
end
end
this should make the boss talk when his health = 60% or less but it should run one time, when I run the code the boss keep saying and attacking all the time. How can I make it run once?
Use a boolean created outside the scope of the function callback:
local has_talked = false
local function SlitherEvents(event, creature, attacker, damage)
if creature:GetHealthPct() <= 60 and not has_talked then
has_talked = true
creature:SendUnitYell("Will punish you all",0)
creature:RegisterEvent(AirBurst, 1000, 1) -- 1 seconds
return
end
end
EDIT
If you are actually using the Eluna Engine's RegisterEvent call, then set the number of repeats to 1 and not 0. This will resolve the issue you had.

Schedule daily function in Corona

Is there a way you can schedule a function to run daily in a Corona SDK App?
function DailyFunction()
print("daily function")
end -- run this function every 24 hours
A literal answer to your question would be:
function DailyFunction()
print("daily function")
end -- run this function every 24 hours
timer.performWithDelay( (1000 * 60 * 60 * 24), DailyFunction )
but I suspect you aren't expecting the user to keep the app open all the time which this would require.
Quite a bit more complex but perhaps what you'll need to do is to schedule a local notification 24 hours in the future. Details of how to do that can be found at http://docs.coronalabs.com/guide/events/appNotification/index.html#ios
Remember that you'll need to reschedule the notification each time it fires.

Timecodes in Rails - time or numeric values?

I'm working on a project that stores data on audio tracks and requires the use of timecodes for the start and end points of the track on the audio. I also need to calculate and display the duration of the track. Eg. a track starts at 0:01:30 and finishes at 0:04:12. So its duration is a total of 2 mins and 42 secs.
The trick is that everything needs to be displayed and handled as timecodes, so in the above example the duration needs to be displayed as 0:02:42.
So my question is how you would store the values? The easiest option would be to store the start and end times as Time in the database. Its very easy to calculate the duration and you can utilise the Rails time helpers in the forms. The only painful part is turning the duration back into a time value for display (since if I supply just the number of seconds to strptime it keeps using the current time to fill in the other fields)
The other option that I considered is storing them as numeric values (as the number of seconds). But then I have to write a lot of code to convert them to and from some type of timecode format and I can't use the Rails time helpers.
Is there another idea that I haven't considered? Is there an easy way to calculate and display the duration as a timecode format?
I would store them as seconds or milliseconds. I've been working on a music library manager/audio player in Ruby, and I actually had to write the two methods you would need. It's not that much code:
# Helper method to format a number of milliseconds as a string like
# "1:03:56.555". The only option is :include_milliseconds, true by default. If
# false, milliseconds won't be included in the formatted string.
def format_time(milliseconds, options = {})
ms = milliseconds % 1000
seconds = (milliseconds / 1000) % 60
minutes = (milliseconds / 60000) % 60
hours = milliseconds / 3600000
if ms.zero? || options[:include_milliseconds] == false
ms_string = ""
else
ms_string = ".%03d" % [ms]
end
if hours > 0
"%d:%02d:%02d%s" % [hours, minutes, seconds, ms_string]
else
"%d:%02d%s" % [minutes, seconds, ms_string]
end
end
# Helper method to parse a string like "1:03:56.555" and return the number of
# milliseconds that time length represents.
def parse_time(string)
parts = string.split(":").map(&:to_f)
parts = [0] + parts if parts.length == 2
hours, minutes, seconds = parts
seconds = hours * 3600 + minutes * 60 + seconds
milliseconds = seconds * 1000
milliseconds.to_i
end
It's written for milliseconds, and would be a lot simpler if it was changed to work with seconds.

Resources