Ansca, please solve "duplicate listeners" behavior.

I have wondered for some time why Corona allows duplicate listeners of the same name/type, and so far I haven’t figured out why this should be possible.

Assume the following code. I intentionally add two Runtime “enterFrame” listeners that call the same function. If you run this code, you’ll notice that removing the listener (after the timed delay) effectively only removes one of them, and so the listener keeps going.

local function running()  
 print("RUNNING")  
end  
  
local function removeIt()  
 print("REMOVED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")  
 Runtime:removeEventListener( "enterFrame", running )  
end  
  
Runtime:addEventListener( "enterFrame", running )  
Runtime:addEventListener( "enterFrame", running )  
  
timer.performWithDelay( 2000, removeIt )  

Obviously this is a silly example, because there should be no reason to add two duplicate listeners. But in the shuffle of programming, in a complicated scenario, it’s not far-fetched at all to imagine 2 duplicate listeners called, resulting in problems/errors and debugging headaches. Imagine a scenario where a collision event triggers a Runtime listener; if two of these collisions occur, or if the phases are not checked carefully, you will end up with multiple listeners running when, most likely, only one is desired.

The same goes for other types of listeners, as far as I know. For example, the most simple touch listener on an object “button” which calls the function “buttonPress” and then performs some action:

button:addEventListener( "touch", buttonPress )

This is all fine unless you want to manage whether the button is active or not, by removing and re-applying its listener. Or when you want to perform a comprehensive cleanup function to remove all listeners, i.e. between levels. If for some reason this button listener was added twice, then there’s a stray hanging out there likely causing problems.

Clearly, there are ways to avoid duplicating listeners (boolean variables with if-then statements, etc.). First and foremost, it’s the programmer’s responsibility to write clean code. However, as a fail-safe, why can’t Corona simply prevent duplicate listeners entirely? If you have a button with a touch listener, well… you have a button with a touch listener! The type (“touch”) and the target function (“buttonPress”) dictates that the button has that specific listener applied. If another addEventListener call is made using the same type and function , Corona should simply ignore it. This would spare us some debugging nightmares when, as I said, duplicate listeners are unintentionally applied. Furthermore, I see no instance when multiple listeners of the same type/function are necessary… and if they never are, but the alternative can cause problems, then Corona should not allow it.

Thoughts or opinions? Notch a +1 if you agree with this fix for a future release of Corona.

Thanks,
Brent Sorrentino
Ignis Design [import]uid: 9747 topic_id: 19153 reply_id: 319153[/import]

Well if it bothers you that much, you can do this when removing listeners.

[lua]for k,v in pairs(Runtime._functionListeners.enterFrame) do
if v==running then
Runtime:removeEventListener(“enterFrame”,v)
end
end[/lua]

It is a bit of a hack really and not “recommended” by Ansca.
Still… does the job. [import]uid: 64174 topic_id: 19153 reply_id: 73876[/import]

I’ve documented this issue months ago: http://developer.anscamobile.com/forum/2011/08/01/possible-addeventlistener-bugs

In general I think the Corona event dispatching functions need a rewrite. I’m currently using my own event dispatching mechanism to get around a bunch of errors I’ve come across. I’ve reported them months ago, but Ansca has yet to respond. I even told Walter face to face.

In general I avoid using Runtime event listeners when possible. For stuff like listening for enterFrame I think you’re better off having one listener and then a table for event handlers to loop through.

For example:

local runtimeListeners = {}  
  
runtimeListeners['myEnterFrameListener'] = somefunction  
  
local function enterFrame(\_e)   
 for k, v in pairs(runtimeListeners) do  
 v(\_e)  
 end  
end  
  
Runtime:addEventListener('enterFrame', enterFrame)  

Voila! No more duplicates! At least you can easily check for them by examining the runtimeListeners table.

If you’re interested you can check out my event dispatching functions in the Spriteloq API. http://www.loqheart.com/spriteloq/downloads/extras/spriteloq_libs.zip Here are the docs explaining how to use them. http://www.loqheart.com/spriteloq/apidocs/files/loq_util-lua.html#loq_listeners

What nice about it is that you can give any table event dispatching and listening functions. Check out the loq_util.lua file and examine the loq_listeners code to see how it works.
[import]uid: 27183 topic_id: 19153 reply_id: 73890[/import]

There’s really nothing to say that duplicate event listeners are inherently good or bad. As you pointed out, if you’re attaching duplicate event listeners unintentionally, something is going on in your code that you probably don’t understand as well as you should.

That said, it would be easy to write your own wrapper function to prevent duplicate event listeners from being attached, at least in the manner that you describe. Corona probably foregoes addressing this issue because of the complexities that can arise when you use anonymous functions, closures, function redefinitions, etc. in between listener assignment. [import]uid: 71767 topic_id: 19153 reply_id: 73954[/import]

To all who responded, I appreciate the feedback and opinions. But as I stated, the issue isn’t about adding work-arounds or custom fail-safes… I can program those easily enough. It’s about fixing what I consider a core Corona “bug”: it should not allow duplicate listeners of the same type targeting the same function. I can’t determine any reason why somebody would intentionally want/need multiple listeners of the same type/function, and since allowing it can result in undesired results or even memory-clogging, I request that Ansca prevents it from happening entirely. Just my 2 cents of course. :slight_smile:
[import]uid: 9747 topic_id: 19153 reply_id: 74104[/import]

This isn’t a “bug”, which is why it was moved to feature requests.

I’ll bring it up in our next meeting.

Peach :slight_smile: [import]uid: 52491 topic_id: 19153 reply_id: 74117[/import]

@IgnisDesign If you’re not looking for help from the community, make it clearer that you’re just ranting.

@peach Thanks. [import]uid: 27183 topic_id: 19153 reply_id: 74142[/import]

@don
That’s a bit harsh!
If you want to let Ansca know your thoughts, what better place than here? The more people requesting something, the faster things get going(hopefully) :slight_smile: [import]uid: 64174 topic_id: 19153 reply_id: 74163[/import]

@Satheesh Maybe it is harsh, but I find it rude and disingenuous for someone to say I appreciate the feedback and in the next sentence say to 3 people trying to help that your feedback was useless. [import]uid: 27183 topic_id: 19153 reply_id: 74170[/import]

I don’t think Ignis meant any offense; if anything, he may be pushing a little strongly his own opinion that the described behavior is a core bug, and not an acceptable default behavior.

I personally disagree with that opinion. I think that if you want to add duplicate event listeners, then go ahead and knock yourself out, regardless of whether you’re doing so intentionally, or you just can’t code well enough to prevent this from happening.

Because of the complexities of how Lua handles scope, object references, aliases, and closures, I’m not so sure you can systematically say that “I can’t determine any reason why somebody would intentionally want/need multiple listeners of the same type/function”, especially since Corona disallows dynamically generated code via loadString. Who knows how clever and creative someone must get when programming suitably advanced functionality.

I do agree that for most cases, duplicate event listeners are probably not what the developer intends. In this case, I believe that we should add an optional boolean flag that tells Runtime to perform duplicate listener prevention.

BTW, Ignis, I love your logo. Reminds me of another logo I very much love, Shiva3D. [import]uid: 71767 topic_id: 19153 reply_id: 74214[/import]

@don, clearly I touched a nerve with this post; it was not meant to be rude or disingenuous as you claim. I’ve been posting in this community for over a year and I don’t recall any occasion where I have “ranted” about anything; I try to thoroughly describe in detail why I’m posting something, especially if I post it under Bug Reports.

The problem, as @dejay and @Peach pointed out, is that I consider this listener issue a “bug” while they consider it a “feature” or perhaps standard behavior. Because I consider it a bug, and I would like to see it squashed, feedback pointing out workarounds are not what I’m looking for. I’m not saying that they are USELESS… by all means, they would all work fine!.. it’s just that they don’t address the core issue. I assumed it was clear in the initial post that I was not looking for workarounds. It was a request to Ansca to consider a solution for this in a future release (and thank you Peach for adding it to your list of meeting notes!). [import]uid: 9747 topic_id: 19153 reply_id: 74249[/import]

Hey guys,

It’s OK to debate this stuff but let’s remember we’re all friends here :slight_smile:

Some issues are going to get under your skin more than others - and in this case Ignis is upset because he feels there is a bug we aren’t addressing while Don is upset he provided feedback that was not appreciated.

Don’s suggestion is excellent and one I am sure will come in handy for those looking for a way to manage this situation.

Ignis, your concerns are valid although as I said, it’s not a bug and something a developer should manage - I wouldn’t call it a feature, just a part of development.

In any case, it will be brought up in the next meeting and we’ll go from there.

In the meantime, healthy discussion and debate is good but just remember everyone here is on the same team. (Team Corona, the winning team ;))

Peach :slight_smile: [import]uid: 52491 topic_id: 19153 reply_id: 74308[/import]

Sorry to everyone. I was the one being an ass by misinterpreting Brent’s words and misdirecting my energy.

I’ve been trying to press the issue with problems regarding the event dispatching system for some time starting back in July with this post: http://developer.anscamobile.com/forum/2011/07/01/runtime-error-nil-unusable-stack-trace-0

It’s a shame it’s taken nearly 5 months for something that is core to Corona to get any attention. Then again there are workarounds, and I know the Ansca guys must be busy.

@Brent Sorry for slighting you. In the future I’ll handle my words with more grace. [import]uid: 27183 topic_id: 19153 reply_id: 74321[/import]

@don, no worries. We all get frustrated sometimes by what we believe Corona should or shouldn’t do, and why Ansca hasn’t delivered it already (when in truth, I imagine they are swamped). If they decide to not address the listener issue (possible) then I’ll absolutely implement your solution which looks both comprehensive and flexible.

Brent
[import]uid: 9747 topic_id: 19153 reply_id: 74443[/import]