Ability to limit a function to run once simultaneously?

Hello,

Is there any way to limit a function so that it can only be run once simultaneously? I have an app where various events might trigger a function to run, and I suspect that it is being run simultaneously at times, which is messing things up. I could use a queue and run the function every frame, but I’m trying to keep things as simple as possible.

Thanks,

  • Bret [import]uid: 168791 topic_id: 31694 reply_id: 331694[/import]

Yes, use a flag-

[lua]local myFlag = false

local function myFunction(event)
if event.phase == “began” and myFlag == false then
myFlag = true
–Do stuff here
elseif event.phase == “ended” then
myFlag = false
end
end[lua]Peach :slight_smile: [import]uid: 52491 topic_id: 31694 reply_id: 126621[/import]

Thanks Peach,

But isn’t there still a little bit of wiggle room that might allow the function to run twice simultaneously, even with a flag? Let me take your code as an example. Let’s pretend that there are two events that cause myFunction() to be called. For argument sake, I’ll call them event A and event B. Here’s your code, just to reiterate:

[lua]local myFlag = false

local function myFunction(event)
if event.phase == “began” and myFlag == false then
myFlag = true
–Do stuff here
elseif event.phase == “ended” then
myFlag = false
end
end[/lua]

Now, let’s assume that A and B run very closely to the same time. So, event A runs line 1. Then event B runs line 1. Then event A runs line 3, then event B runs line 3. Then event A runs line 4, which is

[lua]if event.phase == “began” and myFlag == false then[/lua]

Then event B runs line 4. Both “threads” of code will see myFlag == false, and both will proceed to run the same code.

Is my scenario possible?

My work around is pretty tedious and would require a Lua stack implementation. It would work something like this:

[lua]local function queueMyFunction(argument)
– push argument on a queue
end

local function executeQueue()
– if there’s something on the queue, pop it off and do something
end

obj:addEventListener( “touch”, queueMyFunction)
Runtime:addEventListener(“enterFrame”,executeQueue)[/lua]

Thanks,

  • Bret [import]uid: 168791 topic_id: 31694 reply_id: 126622[/import]

Hi Bret,

I understand your concern, but no, I’m fairly certain that the situation you’re describing cannot happen. (I use flags similar to what Peach described without any issues.)

Let’s suppose event A happens slightly before event B. The closest they could possibly be is one frame apart, i.e., event A happening one frame before event B. In Corona, all of the calculations for a particular frame happen before it proceeds to the next frame (at least, that’s how I’ve always understood it to work). That means that when event A happens and myFunction is called for the first time, it will fully execute before event B triggers myFunction.

Said differently, I don’t believe events give rise to parallel threads that could conflict in the way you’re describing.

Now, there’s the question of what happens when event A and event B happen simultaneously, i.e., within the same frame. In that case I imagine one of them still calls and completely executes myFunction first (perhaps an internal queue exists within Corona or Lua for dispatching events), but that would be easy to set up a sample case to test out and verify.

Hope this helps.

  • Andrew [import]uid: 109711 topic_id: 31694 reply_id: 126638[/import]

Hi Andrew,

Yeah, you appear to be right. I wrote a pretty simple function to test it out. This isn’t the exact function, but you’ll get the idea:

[lua]local thread_count = 0

function test()
thread_count = thread_count + 1
… do some stuff …
if thread_count == 2 then print(“something”) end
thread_count = thread_count - 1
end[/lua]

thread_count never reached 2, so it appears that the code isn’t being run twice at the same time by different events. Well, I suppose that’s good to know. My bug still exists, so back to the drawing board.

Cheers,

  • Bret [import]uid: 168791 topic_id: 31694 reply_id: 126648[/import]

Yes, use a flag-

[lua]local myFlag = false

local function myFunction(event)
if event.phase == “began” and myFlag == false then
myFlag = true
–Do stuff here
elseif event.phase == “ended” then
myFlag = false
end
end[lua]Peach :slight_smile: [import]uid: 52491 topic_id: 31694 reply_id: 126621[/import]

Thanks Peach,

But isn’t there still a little bit of wiggle room that might allow the function to run twice simultaneously, even with a flag? Let me take your code as an example. Let’s pretend that there are two events that cause myFunction() to be called. For argument sake, I’ll call them event A and event B. Here’s your code, just to reiterate:

[lua]local myFlag = false

local function myFunction(event)
if event.phase == “began” and myFlag == false then
myFlag = true
–Do stuff here
elseif event.phase == “ended” then
myFlag = false
end
end[/lua]

Now, let’s assume that A and B run very closely to the same time. So, event A runs line 1. Then event B runs line 1. Then event A runs line 3, then event B runs line 3. Then event A runs line 4, which is

[lua]if event.phase == “began” and myFlag == false then[/lua]

Then event B runs line 4. Both “threads” of code will see myFlag == false, and both will proceed to run the same code.

Is my scenario possible?

My work around is pretty tedious and would require a Lua stack implementation. It would work something like this:

[lua]local function queueMyFunction(argument)
– push argument on a queue
end

local function executeQueue()
– if there’s something on the queue, pop it off and do something
end

obj:addEventListener( “touch”, queueMyFunction)
Runtime:addEventListener(“enterFrame”,executeQueue)[/lua]

Thanks,

  • Bret [import]uid: 168791 topic_id: 31694 reply_id: 126622[/import]

Hi Bret,

I understand your concern, but no, I’m fairly certain that the situation you’re describing cannot happen. (I use flags similar to what Peach described without any issues.)

Let’s suppose event A happens slightly before event B. The closest they could possibly be is one frame apart, i.e., event A happening one frame before event B. In Corona, all of the calculations for a particular frame happen before it proceeds to the next frame (at least, that’s how I’ve always understood it to work). That means that when event A happens and myFunction is called for the first time, it will fully execute before event B triggers myFunction.

Said differently, I don’t believe events give rise to parallel threads that could conflict in the way you’re describing.

Now, there’s the question of what happens when event A and event B happen simultaneously, i.e., within the same frame. In that case I imagine one of them still calls and completely executes myFunction first (perhaps an internal queue exists within Corona or Lua for dispatching events), but that would be easy to set up a sample case to test out and verify.

Hope this helps.

  • Andrew [import]uid: 109711 topic_id: 31694 reply_id: 126638[/import]

Hi Andrew,

Yeah, you appear to be right. I wrote a pretty simple function to test it out. This isn’t the exact function, but you’ll get the idea:

[lua]local thread_count = 0

function test()
thread_count = thread_count + 1
… do some stuff …
if thread_count == 2 then print(“something”) end
thread_count = thread_count - 1
end[/lua]

thread_count never reached 2, so it appears that the code isn’t being run twice at the same time by different events. Well, I suppose that’s good to know. My bug still exists, so back to the drawing board.

Cheers,

  • Bret [import]uid: 168791 topic_id: 31694 reply_id: 126648[/import]