how to check if listener already exists

hy

how do i check if an object still has an eventListener?
i wanna do something like this:

Runtime:addEventListener( “enterFrame”, startRotation )

if(exists eventlistner)then
Runtime:removeEventListener( “enterFrame”, startRotation )
end

when i do remove and the EventListener doesnt exist, it gives an error.

thks [import]uid: 92107 topic_id: 18324 reply_id: 318324[/import]

I think you can do something like this
[lua]if(Runtime._functionListeners.enterFrame)then
Runtime:removeEventListener( “enterFrame”, startRotation )
end[/lua] [import]uid: 64174 topic_id: 18324 reply_id: 70203[/import]

Have you figured out how to do this? The suggestion does not appear to work. [import]uid: 97768 topic_id: 18324 reply_id: 71077[/import]

@Houde That should work fine.
[lua]Runtime._functionListeners.enterFrame[/lua]
contains a table of existing enterFrame functions.

If you have more than 1 enterFrame listener, you can always do the following

[lua]Runtime:addEventListener(“enterFrame”,function1)
Runtime:addEventListener(“enterFrame”,function2)
if Runtime._functionListeners.enterFrame then
for _,func in pairs(Runtime._functionListeners.enterFrame) do
if func==function1 then
Runtime:removeEventListener( “enterFrame”,func )
end
end
end[/lua] [import]uid: 64174 topic_id: 18324 reply_id: 71120[/import]

Hey,
I am also having trouble with this. In my situation I want the listener to exist on a display object until the display object hits something. Something like the below:

local function spawn(e)   
 local b = bean.newBean(colour);  
 b:addEventListener("collision", touchCheck);   
 b:addEventListener("touch", move);   
end  

local function touchCheck(e) local object1 = e.target local object2 = e.other if(e.phase == "began") then if(object1.\_functionListeners.touch)then object1:removeEventListener("touch", move); end end end [import]uid: 31694 topic_id: 18324 reply_id: 90738[/import]

try this:

local function touchCheck(e) local object1 = e.target local object2 = e.other if(e.phase == "began") then if(object1)then object1.\_functionListeners=nil end end end [import]uid: 92107 topic_id: 18324 reply_id: 90763[/import]

Since object1 refers to the display object, and therefore will always be true, won’t I have the same issue? Also would that code not remove all the listeners? I only want to remove the touch listener. [import]uid: 31694 topic_id: 18324 reply_id: 90924[/import]

Help? [import]uid: 31694 topic_id: 18324 reply_id: 91068[/import]

You can eliminate the error by doing the following:

local function touchCheck(e)  
 local object1 = e.target  
 local object2 = e.other  
 if(e.phase == "began") then  
 pcall(function() object1:removeEventListener("touch", move) end)  
 end  
end  

Jeff

[import]uid: 14119 topic_id: 18324 reply_id: 91087[/import]

Well it certainly got rid of the error, but it didn’t get rid of the listener either.

The error I was getting before was “ERROR: nil key supplied for property lookup” [import]uid: 31694 topic_id: 18324 reply_id: 91099[/import]

. [import]uid: 31694 topic_id: 18324 reply_id: 91100[/import]

If there’s an event listener to remove, that should work.
One thing that could cause the ‘nil’ error is the ‘move’ function is defined after the ‘touchCheck’ function making the reference to ‘move’ out-of-scope to the ‘touchCheck’ function. Make sure ‘move’ function is defined before the ‘touchCheck’ function.
Should be in this order:

local function move(e)  
  
end  
  
local function touchCheck(e)  
  
end  
  
local function spawn(e)  
  
end  

Or you can use forward references:

-- somewhere at the top of the file  
local move = function() end;  
local touchCheck = function() end;  
local spawn = function() end;  
  
-- defined later in the file  
function touchCheck(e)  
  
end  
  
function spawn(e)  
  
end  
  
function move(e)  
  
end  
  

One way to ‘ignore’ the touch would be using a flag.

--This is your 'move' function:  
local function move(e)  
 local object1 = e.target  
 local obj1Type = e.target.type  
 if (obj1Type and obj1Type == "bean" and object1.touchEnabled) then  
  
--  
-- Do whatever you need to do for move  
--  
 end  
end  
  
local function touchCheck(e)  
 local object1 = e.target  
 local obj1Type = e.target.type  
 local object2 = e.other  
 local obj2Type = e.other.type  
 -- Check both objects to see if they are 'beans'  
 if(e.phase == "began") then  
 if (obj1Type and obj1Type == "bean")  
 then object1.touchEnabled = false;  
 end;  
 if (obj2Type and obj2Type == "bean")  
 then object2.touchEnabled = false;  
 end;  
 end  
end  
  
local function spawn(e)   
 local b = bean.newBean(colour);  
 b.touchEnabled = true;  
 b.type = "bean"  
 b:addEventListener("collision", touchCheck);   
 b:addEventListener("touch", move);   
end  

This code is not tested and may contain some errors but you should get the idea.

Jeff

[import]uid: 14119 topic_id: 18324 reply_id: 91146[/import]

Thanks heaps. I tried out both the solutions above and I had some limited success. Both now allow me to drag only the last spwaned bean.

The only problem now is if another bean spawns while I am still in the middle of a “moved” phase I am unable to drag any further beans.

Is there anyway to interupt a “touch” event if a display object is spawned to prevent this? [import]uid: 31694 topic_id: 18324 reply_id: 91157[/import]

You can use a table listener which will treat each bean separately.

local function spawn(e)   
 local b = bean.newBean(colour);  
 b.touchEnabled = true;  
 b.type = "bean"  
 --This is your 'move' function:  
 local function b:touch(e)  
 local object1 = e.target  
 local obj1Type = e.target.type  
 if (obj1Type and obj1Type == "bean" and object1.touchEnabled) then  
  
 --  
 -- Do whatever you need to do for move  
 --  
 end  
 end  
  
 local function b:collision(e)  
 local object1 = e.target  
 local obj1Type = e.target.type  
 local object2 = e.other  
 local obj2Type = e.other.type  
 -- Check both objects to see if they are 'beans'  
 if(e.phase == "began") then  
 if (obj1Type and obj1Type == "bean")  
 then object1.touchEnabled = false;  
 end;  
 if (obj2Type and obj2Type == "bean")  
 then object2.touchEnabled = false;  
 end;  
 end  
 end  
   
 b:addEventListener("collision", b);   
 b:addEventListener("touch", b);   
end  

The check for ‘bean’ is probably not needed with table listener.
Let me know if that helps.

Jeff
[import]uid: 14119 topic_id: 18324 reply_id: 91179[/import]

thanks, I tried implimenting the code you suggested but I’m getting an error ‘)’ expected near ‘:’ on line 165 (line 8 below) which is the line with “local function b:touch(e)”

[code]
local function spawn(e)
if(ready == true) then
i = i + 1;
local rand = m.random(1,6);
local colour = beanColours[rand];
local b = bean.newBean(colour);

local function b:touch(e)
if(e.target.touchEnabled == true) then
local t = e.target

local phase = e.phase
if “began” == phase then
– Make target the top-most object
local parent = t.parent;
parent:insert( t );
display.getCurrentStage():setFocus( t );

– Spurious events can be sent to the target, e.g. the user presses
– elsewhere on the screen and then moves the finger over the target.
– To prevent this, we add this flag. Only when it’s true will “move”
– events be sent to the target.
t.isFocus = true;

– Store initial position
t.x0 = e.x - t.x;
t.y0 = e.y - t.y;
elseif t.isFocus then
if “moved” == phase then
– Make object move (we subtract t.x0 so that moves are
– relative to initial grab point, rather than object “snapping”).
t.x = e.x - t.x0;
–t.y = e.y - t.y0;
elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil );
t.isFocus = false;
end
end

– Important to return true. This tells the system that the event
– should not be propagated to listeners of any objects underneath.
return true;

end
end

local function b:collision(e)
if (e.other.type == “floor” or e.other.type == “bean”) then
e.target.touchEnabled = false;
end
touchCheck(e);
matchCheck(e);
end

b:addEventListener(“collision”, b);
b:addEventListener(“touch”, b);
beans[i] = b;
foreground:insert(beans[i]);

end
end
[/code] [import]uid: 31694 topic_id: 18324 reply_id: 91237[/import]

I seem to have fixed the above issue by changing the removing the “local” from the functions. However, I’m still getting the bug where if a new bean spawns while I am moving the previous bean, I will no longer be able to move the newly created beans. [import]uid: 31694 topic_id: 18324 reply_id: 91239[/import]

Your right about the ‘local’, it did not need to be there.

Where is ‘touchEnabled’ being set to ‘true’?
Why are you still calling touchCheck(e) and ‘matchCheck(e)’? That code should be in the ‘collision’ function.

I’m just trying to give you concepts, not tested and complete code. If you want to give me your entire code, I’ll try to help you as best I can. You can post it here or zip it up and email it to jeffbyrd “at” att “dot” net.

Jeff
[import]uid: 14119 topic_id: 18324 reply_id: 91265[/import]

Try adding the following code to the end of the spawn function:

 -- Important to return true. This tells the system that the event  
 -- should not be propagated to listeners of any objects underneath.  
 return true;  
 else  
 if (t.isFocus) then  
 display.getCurrentStage():setFocus(nil);  
 t.isFocus = false;  
 end;  
 end  
 end  

That will allow the bean to be moved until it hits something. If you need to allow it to be moved until you release your finger, then there’s different code which I can give you.
You have a lot of ‘global’ variables that probably should be made local which could improve the game response. If you need help with that, let me know.

Jeff

[import]uid: 14119 topic_id: 18324 reply_id: 91344[/import]

Thanks that would be really helpful. I am setting touchEnabled to true in my bean properties in my bean.lua file. I have moved the touchCheck and matchCheck code into the collision function. [import]uid: 31694 topic_id: 18324 reply_id: 91299[/import]

I’m not sure if this is exactly what you had in mind but it seems to have worked.

I inserted this into the collision function so that on collision it is setting the focus to nil at the same time as setting touchEnable to false.

if (object2.type == "floor" or object2.type == "bean") then  
 object1.touchEnabled = false;  
 if (object1.isFocus) then  
 display.getCurrentStage():setFocus(nil);  
 object1.isFocus = false;  
 end;  
end  

I unfortunately need help with just about everything. I have a few more features I want to impliment and I feel like I am going to have to create a new thread for every one of them. [import]uid: 31694 topic_id: 18324 reply_id: 91417[/import]