Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Start Event at OS Time
Started by PHB Feb 20 2019 11:13 PM

4 replies to this topic

Best Answer XeduR @Spyric , 21 February 2019 - 02:14 AM

The app is most likely crashing due to infinite loops inside your startMetronome function. You didn't include code where you defined startTime or stopData, but I am guessing that at least one of their until conditions is never met. In fact, it is very unlikely for 

until os.time() == startTime

to ever be met since the loop would break only in the event that os.time() is exactly the same as startTime. If you were to replace the condition with ">=" then it would stop if the os.time() is ever the same or higher than startTime.

However, your function has a more fundamental flaw in it. That is, the entire idea of using a loop like this is wrong. What is going on now is that Corona is going to fire the timer multiple times every frame until the condition is met.


I'd recommend sticking more to the timers, i.e. something like:
 

local getTimer = system.getTimer
local startTime, stopTime
local tickTimer

local function metronomeTick( tickTime )
	if getTimer() < stopTime then
		print("tick", "time passed: "..(getTimer()-startTime))
		tickTimer = timer.performWithDelay( tickTime, function() metronomeTick( tickTime ) end )
	end
end

local function startMetronome( tickTime, duration )
	startTime = getTimer()
	stopTime = startTime + duration
	tickTimer = timer.performWithDelay( tickTime, function() metronomeTick( tickTime ) end )
end

startMetronome( 20, 2000 )

I think that this is a lot closer to what you want. But I still left you with a bit more coding to do.

If you run the code, you'll see that the time passed between the prints is actually more than 20ms. This is due to Corona being frame-based and if you run the app at 60fps, the events can only execute once every ~17ms, which is problematic if you plan to run your timers every 20ms. Additionally, a user's device never performs constantly at 60fps. Any lag spike or performance drop in general is going to temporarily drop it, which again causes inaccuracies for the timers.

Now, these inaccuracies can be fixed to a great extent by applying delta time. You'll find a good tutorial and sample code for it at http://www.sdknews.com/cross-platform/corona/guest-tutorial-delta-time-in-corona

Hopefully this helps!

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

PHB

[GLOBAL: userInfoPane.html]
PHB
  • Observer

  • 3 posts
  • Corona SDK

Hey, I know Corona is event-based and whatnot. But I am making a metronome-based app so timing is very important. I'll spare you the unnecessary details, but what I need to know is how I can start a function at a specific OS time.

 
local function metronomeTick()
	print("tick")
end

local function startMetronome()
	started = true
	repeat
	timer.performWithDelay(20, metronomeTick)--This Line
	until os.time() == startTime
	repeat
		timer.performWithDelay(60/tempo, metronomeTick)
		local stopData = send:receive()
	until stopData and stopData == "Stop"
end
 

The line I labelled should make it tick every 20 milliseconds until the os time reaches the variable startTime. However, the app just crashes. What should I do instead? Thanks.



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 687 posts
  • Corona SDK

  Best Answer

The app is most likely crashing due to infinite loops inside your startMetronome function. You didn't include code where you defined startTime or stopData, but I am guessing that at least one of their until conditions is never met. In fact, it is very unlikely for 

until os.time() == startTime

to ever be met since the loop would break only in the event that os.time() is exactly the same as startTime. If you were to replace the condition with ">=" then it would stop if the os.time() is ever the same or higher than startTime.

However, your function has a more fundamental flaw in it. That is, the entire idea of using a loop like this is wrong. What is going on now is that Corona is going to fire the timer multiple times every frame until the condition is met.


I'd recommend sticking more to the timers, i.e. something like:
 

local getTimer = system.getTimer
local startTime, stopTime
local tickTimer

local function metronomeTick( tickTime )
	if getTimer() < stopTime then
		print("tick", "time passed: "..(getTimer()-startTime))
		tickTimer = timer.performWithDelay( tickTime, function() metronomeTick( tickTime ) end )
	end
end

local function startMetronome( tickTime, duration )
	startTime = getTimer()
	stopTime = startTime + duration
	tickTimer = timer.performWithDelay( tickTime, function() metronomeTick( tickTime ) end )
end

startMetronome( 20, 2000 )

I think that this is a lot closer to what you want. But I still left you with a bit more coding to do.

If you run the code, you'll see that the time passed between the prints is actually more than 20ms. This is due to Corona being frame-based and if you run the app at 60fps, the events can only execute once every ~17ms, which is problematic if you plan to run your timers every 20ms. Additionally, a user's device never performs constantly at 60fps. Any lag spike or performance drop in general is going to temporarily drop it, which again causes inaccuracies for the timers.

Now, these inaccuracies can be fixed to a great extent by applying delta time. You'll find a good tutorial and sample code for it at http://www.sdknews.com/cross-platform/corona/guest-tutorial-delta-time-in-corona

Hopefully this helps!


  • agramonte and PHB like this

[TOPIC: post.html]
#3

agramonte

[GLOBAL: userInfoPane.html]
agramonte
  • Corona Geek

  • 1,088 posts
  • Corona SDK

@xedur that is one of the most lucid post I have read in at least a few weeks. When I grow up I want to write like you.



[TOPIC: post.html]
#4

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 687 posts
  • Corona SDK

Thanks @agramonte! Let's hope the OP finds the post as lucid as you did :D


  • PHB likes this

[TOPIC: post.html]
#5

PHB

[GLOBAL: userInfoPane.html]
PHB
  • Observer

  • 3 posts
  • Corona SDK

Thanks @agramonte! Let's hope the OP finds the post as lucid as you did :D

Lucid indeed




[topic_controls]
[/topic_controls]