Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
  • 0
XFactHD

Event.listen() not correctly triggering

Question

In my Base Control Program I define a callback function:

local function getClick(_, _, x, y, _, _)
  if x > 44 and x < 50 and y == 4 and active == false then
    setStatus(true)
  elseif x > 44 and x < 50 and y == 4 and active == true then
    setStatus(false)
  elseif x > 44 and x < 50 and y == 6 and safety == false then
    safety = true
  elseif x > 44 and x < 50 and y == 6 and safety == true then
    safety = false
  elseif x > 44 and x < 50 and y == 20 and spawnEnder == false then
    setSpawnEnder(true)
  elseif x > 44 and x < 50 and y == 20 and spawnEnder == true then
    setSpawnEnder(false)
  elseif x > 44 and x < 50 and y == 22 and spawnZS == false then
    setSpawnZS(true)
  elseif x > 44 and x < 50 and y == 22 and spawnZS == true then
    setSpawnZS(false)
  elseif x == 82 and y == 1 then
    shutdown()
  end
end

and just before I start the main loop I create an event listener via event.listen("touch", getClick).

When I run the program and click on the screen, nothing happens.

 

If I try the same with the following code:

local function getClick(_, _, x, y, _, _)
  print("XCoord: " ..x.. " YCoord: " ..y)
end

event.listen("touch", getClick)

while true do

end

and run the program and click on the screen, at first nothing happens, but as soon as the program crashes with "Too long without yielding!" the x and y coords for all touch events get printed correctly. If I click on the screen after the program crashed, I still get the coords printed on the screen as if the program was running.

Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

OC has no real threading or background processes. This means that even "background" listeners only run when you (indirectly) tell them to. In an empty loop like while true do end nothing happens at all, and at some point OC kills the program because it ran too long without checking for events. Event handling happens in the event.pull function - when you call it, it waits for the next event to happen, then calls any listener functions for that event and returns the event name and data. You can also set a filter so that only specific events are caught and returned by event.pull (listeners are still called for all events). For example, this loop will run forever until you press Ctrl+C (which fires an "interrupted" event):

local event = require("event")

while event.pull(nil, "interrupted") == nil do
    
end

The first argument to event.pull is the timeout. I'm not sure if a nil timeout actually means "wait forever" or defaults to something like 60 seconds, so just in case I put it in a loop that runs as long as no "interrupted" event was received (i. e. event.pull returned nil). Because event.pull is called, event listeners will still be called while the loop is running.

Link to post
Share on other sites
  • 0

The little program with the empty while loop was just a test program. The while loop just keeps the program running until OC kills it.

In my Base Control Program I need the while loop for the main code.

If I use event.listen() then I can't call the listener in the main loop. Every forum post on touch events tells me to do exactly what I did in this program.

Link to post
Share on other sites
  • 0

your event listener should not be local since the listener events run in the shells context just like the lua interpreter

 

wrap your local variables/functions in the handler as enclosures

 

you can define them elsewhere and just copy them into the scope of your handler to use as upvalues

arg = {...}

function eventhandler(event, ...)

params = {...}

--because upvalues for enclosure
methods = {table of your methods}

variables = {table of your variables}

end

--Check tmp under root for a log that depicts any silent errors the program may have encountered during program execution this will likely show you what issues you might be running into.

if arg[1] == "unreg" then
   event.ignore("touch", eventhandler)
   os.exit(0)
end

--register your event listener do not un-listen for it

event.listen("touch", eventhandler)

with the arguments if you call your program with program unreg it will un-register the listener for you.

Link to post
Share on other sites
  • 0

@Elsys656 That's not how Lua works. Whether or not you have a local before the function name doesn't matter - you're passing the function value to event.listen, not its name. Theoretically you could even do eventhandler = nil afterwards and the code would still work, as the function is not actually deleted.

 

In fact in Lua you almost never want to make a variable not local, because then it will land in the global namespace shared by all libraries and programs (the shell might do additional sandboxing, but you shouldn't rely on that).

 

I'm also quite sure that your unreg command won't work like this either. Every time your program is run, a new function value is created and assigned to the name eventhandler, which is different from every other function that you previously created and passed to event.listen. When you pass your new function to event.ignore, no matching listener will be found and nothing will be unregistered.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.