Programmatically send event

Hi, I have a scenario. I have two buttons for navigation to left and right. Now I want to add a swipe function as well, but I want to reuse my old function for the navigation. Is it possible to programmatically send event to my functions from another function?

example:

counter = counter + 1;  
event[counter] = {};  
event[counter].phase = "began"  
  
myFunction( event );  
  

Joakim
[import]uid: 81188 topic_id: 31894 reply_id: 331894[/import]

(Re-edited. Pasted my answer in wrong order originally).

Yes. It is possible. You can do a few different things:

  1. Call your own functions from within event handlers:
function customFunction(event)  
... do something with the 'event'  
end  
function customFunction2(event)  
... do something with the 'event'  
end  
  
function myTouchListener( event )  
  
 ... whatever code you want here  
  
 customFunction(event)  
 customFunction2(event)  
  
 ... whatever code you want here  
  
 return true  
end  
  
Runtime:addEventListener( "touch", myTouchListener) -- Works similarly for table listener too  
  1. You can also dispatch custom events if you want:
function customFunction(event)  
... do something with the 'event'  
end  
function customFunction2(event)  
... do something with the 'event'  
end  
  
function myTouchListener( event )  
  
 ... whatever code you want here   
  
 local myEvent = event -- Note: better to copy event into myEvent (http://stackoverflow.com/questions/640642/how-do-you-copy-a-lua-table-by-value)  
 -- In this case myEvent and event are the same table,  
  
 event.name = "func1"  
 Runtime:dispatchEvent( event ) -- executes customFunction()  
  
 event.name = "func2"  
 Runtime:dispatchEvent( event ) -- executes customFunction2()  
  
 ... whatever code you want here  
  
 return true  
end  
  
Runtime:addEventListener( "touch", myTouchListener) -- Works similarly for table listener too  
Runtime:addEventListener( "func1", customFunction) -- Works similarly for table listener too  
Runtime:addEventListener( "func2", customFunction2) -- Works similarly for table listener too  

See this link for more details on *:dispatchEvent() ==> http://developer.coronalabs.com/reference/index/objectdispatchevent

Also, if I missed the point of your question please write back and elaborate.

Cheers,
Ed
Roaming Gamer, LLC.
SSK for Corona SDK (github) (videos)
[import]uid: 110228 topic_id: 31894 reply_id: 127260[/import]

Great Ed, I think that I have to go for the Dispatch example you wrote. Since that my swipe function uses the “moved” event.phase to trigger then navigation - I have to send an “began” event to my other function when that occurs. I will do some testing with this and see if it helps me.

Thanks!

Joakim [import]uid: 81188 topic_id: 31894 reply_id: 127292[/import]

Hmmm, I cant manage to sort out my mind here so I will fill in some code to see if you can help me out here.

First of all, I have my original function for the touch based navigation. It is complex so I just pasted in the logic here and this is the code I want to execute from my other listener.

nextAnimal = function(event)  
  
 if (nextAnim.alpha==1 and isScrolling==false and event.phase=="began" and nextAnim.touchId == nil and animalGroup.active == nil) then   
  
 nextAnim.touchId = event.id  
 display.getCurrentStage():setFocus(event.target, event.id)  
  
 -- All my code runs here in the "began" event.phase...  
  
  
 elseif event.phase == "ended" and nextAnim.touchId == event.id then  
  
 nextAnim.touchId = nil;  
 display.getCurrentStage():setFocus(event.target,nil)  
 end  
end  
  
nextAnim:addEventListener("touch", nextAnimal)   

So that was my touch based navigation that I want to execute from the following function.

local scrollMe = function( event )  
  
 local myEvent = event   
  
 if event.phase == "began" and event.target.id == nil then  
 event.target.id = event.id  
 display.getCurrentStage():setFocus( event.target, event.id )   
 x0 = event.x  
  
 elseif event.phase=="moved" and event.target.id == event.id then  
 if x0 \< event.x then  
 --PrevAnimal  
  
 .. And this is one place where I want to call the touchbased function  
 elseif x0 \> event.x then  
 --NextAnimal  
  
 .. And this is the other place where I want to call the touchbased function  
 end  
  
 elseif event.phase=="ended" then  
  
 display.getCurrentStage():setFocus( event.target, nil )   
 event.target.id = nil;  
 end  
end  
  
--Swipe area  
local swipeArea = display.newRect(0,70,screenW,screenH)  
swipeArea.isVisible = false;  
swipeArea.isHitTestable = true ;  
swipeArea:addEventListener("touch",scrollMe)  
  

So I guess that I have to do something, but I have never worked with dispatch before, so it is for me a little bit of hokuspokus :slight_smile:

regards, Joakim [import]uid: 81188 topic_id: 31894 reply_id: 127313[/import]

(Re-edited. Pasted my answer in wrong order originally).

Yes. It is possible. You can do a few different things:

  1. Call your own functions from within event handlers:
function customFunction(event)  
... do something with the 'event'  
end  
function customFunction2(event)  
... do something with the 'event'  
end  
  
function myTouchListener( event )  
  
 ... whatever code you want here  
  
 customFunction(event)  
 customFunction2(event)  
  
 ... whatever code you want here  
  
 return true  
end  
  
Runtime:addEventListener( "touch", myTouchListener) -- Works similarly for table listener too  
  1. You can also dispatch custom events if you want:
function customFunction(event)  
... do something with the 'event'  
end  
function customFunction2(event)  
... do something with the 'event'  
end  
  
function myTouchListener( event )  
  
 ... whatever code you want here   
  
 local myEvent = event -- Note: better to copy event into myEvent (http://stackoverflow.com/questions/640642/how-do-you-copy-a-lua-table-by-value)  
 -- In this case myEvent and event are the same table,  
  
 event.name = "func1"  
 Runtime:dispatchEvent( event ) -- executes customFunction()  
  
 event.name = "func2"  
 Runtime:dispatchEvent( event ) -- executes customFunction2()  
  
 ... whatever code you want here  
  
 return true  
end  
  
Runtime:addEventListener( "touch", myTouchListener) -- Works similarly for table listener too  
Runtime:addEventListener( "func1", customFunction) -- Works similarly for table listener too  
Runtime:addEventListener( "func2", customFunction2) -- Works similarly for table listener too  

See this link for more details on *:dispatchEvent() ==> http://developer.coronalabs.com/reference/index/objectdispatchevent

Also, if I missed the point of your question please write back and elaborate.

Cheers,
Ed
Roaming Gamer, LLC.
SSK for Corona SDK (github) (videos)
[import]uid: 110228 topic_id: 31894 reply_id: 127260[/import]

Great Ed, I think that I have to go for the Dispatch example you wrote. Since that my swipe function uses the “moved” event.phase to trigger then navigation - I have to send an “began” event to my other function when that occurs. I will do some testing with this and see if it helps me.

Thanks!

Joakim [import]uid: 81188 topic_id: 31894 reply_id: 127292[/import]

Hmmm, I cant manage to sort out my mind here so I will fill in some code to see if you can help me out here.

First of all, I have my original function for the touch based navigation. It is complex so I just pasted in the logic here and this is the code I want to execute from my other listener.

nextAnimal = function(event)  
  
 if (nextAnim.alpha==1 and isScrolling==false and event.phase=="began" and nextAnim.touchId == nil and animalGroup.active == nil) then   
  
 nextAnim.touchId = event.id  
 display.getCurrentStage():setFocus(event.target, event.id)  
  
 -- All my code runs here in the "began" event.phase...  
  
  
 elseif event.phase == "ended" and nextAnim.touchId == event.id then  
  
 nextAnim.touchId = nil;  
 display.getCurrentStage():setFocus(event.target,nil)  
 end  
end  
  
nextAnim:addEventListener("touch", nextAnimal)   

So that was my touch based navigation that I want to execute from the following function.

local scrollMe = function( event )  
  
 local myEvent = event   
  
 if event.phase == "began" and event.target.id == nil then  
 event.target.id = event.id  
 display.getCurrentStage():setFocus( event.target, event.id )   
 x0 = event.x  
  
 elseif event.phase=="moved" and event.target.id == event.id then  
 if x0 \< event.x then  
 --PrevAnimal  
  
 .. And this is one place where I want to call the touchbased function  
 elseif x0 \> event.x then  
 --NextAnimal  
  
 .. And this is the other place where I want to call the touchbased function  
 end  
  
 elseif event.phase=="ended" then  
  
 display.getCurrentStage():setFocus( event.target, nil )   
 event.target.id = nil;  
 end  
end  
  
--Swipe area  
local swipeArea = display.newRect(0,70,screenW,screenH)  
swipeArea.isVisible = false;  
swipeArea.isHitTestable = true ;  
swipeArea:addEventListener("touch",scrollMe)  
  

So I guess that I have to do something, but I have never worked with dispatch before, so it is for me a little bit of hokuspokus :slight_smile:

regards, Joakim [import]uid: 81188 topic_id: 31894 reply_id: 127313[/import]

@jkrassman,

Sorry! I subscribed to this thread, but didn’t see the update e-mail.

I’ve looked over your original question again and your latest update and have some questions and suggestions.

Originally you said you have two buttons (left and right) for navigation.
1. Are you still using these buttons in your game/app?
2. Are you you also supporting a swipe functionality?

I will assume that the answers to questions #1 and #2 are “Yes” and that you want two pushbuttons and a swipe function that do similar things.

With the above assumption in mind, you need to do a few things.

  1. Forget about dispatch. I think you’ll be better off with direct function calls.

  2. Make copies of your original code and set that code aside.

  3. Gut your original callback(s) for left and right button pushes. That is remove all of the code that does utility work like updating your game logic, creating/destroying/modifying display objects, etc.

  4. Take the utility code you removed and put it one or more new utility functions. It is OK to pass the event table to these functions if they need something from the table to do their work.

  5. Take the gutted callback(s) from step #2 and insert calls to your utility code from step #3.

  6. Substitute the new callback(s) for your old callback(s).

  7. Test the changes and be sure you didn’t break anything.

  8. Write a new callback for the swipe event. This callback should only make decisions about the swipe. In the appropriate places, call the extracted utility code from step #3.

  9. Hook up your new swipe callback and test it out.

The following is a purely hypothetical example of what I just layed out in the steps above.

My hypothetical original button code

left\_touch = function( event )  
  
 if event.phase == "began" then  
  
 -- LEFT WORK A  
  
 elseif event.phase == "moved" then  
  
 -- LEFT WORK B  
  
 elseif event.phase == "ended" or event.phase == "cancelled" then  
  
 -- LEFT WORK C  
  
 end  
  
 -- LEFT WORK D  
  
end  
  
leftButton:addEventListener("touch",left\_touch)  
  
-- Assume similar for right button  
  

My gutted and modified button code

-- Note: Following functions can have more arguments if you need them  
left\_workA = function(event)   
 -- LEFT WORK A  
end  
  
left\_workB = function(event)  
 -- LEFT WORK B  
end  
  
left\_workC = function(event)  
 -- LEFT WORK C  
end  
  
left\_workD = function(event)  
 -- LEFT WORK D  
end  
new\_left\_touch = function( event )  
  
 if event.phase == "began" then  
 left\_workA( event )  
  
 elseif event.phase == "moved" then  
 left\_workB( event )  
  
 elseif event.phase == "ended" or event.phase == "cancelled" then  
 left\_workC( event )  
  
 end  
  
 left\_workD( event )  
end  
leftButton:addEventListener("touch",new\_left\_touch)  
  
-- Assume similar for right button  

My hypothetical swipe code

scrollMe = function (event)  
  
 if event.phase == "began" then  
  
 if( ??? is left swipe ??? ) then  
 left\_workA( event )  
 else  
 right\_workA( event )  
 end  
 elseif event.phase == "moved" then  
  
 if( ??? is left swipe ??? ) then  
 left\_workB( event )  
 else  
 right\_workB( event )  
 end  
  
 elseif event.phase == "ended" or event.phase == "cancelled" then  
  
 if( ??? is left swipe ??? ) then  
 left\_workC( event )  
 else  
 right\_workC( event )  
 end  
  
 end  
  
 left\_workD( event )  
 right\_workD( event )  
end  
  
swipeArea:addEventListener("touch",scrollMe)  

I hope this helps. I know getting your head around touch inputs is challenging, especially when you introduce intermediate inputs like swiping. Just keep working at it. I know you’ll eventually crack this nut.

Cheers,
Ed
Roaming Gamer, LLC.
SSK for Corona SDK (github) (videos)
[import]uid: 110228 topic_id: 31894 reply_id: 127728[/import]

Sorry, I am not getting emails either? I will look into your suggestion!

Thanks, Joakim [import]uid: 81188 topic_id: 31894 reply_id: 127821[/import]

@jkrassman,

Sorry! I subscribed to this thread, but didn’t see the update e-mail.

I’ve looked over your original question again and your latest update and have some questions and suggestions.

Originally you said you have two buttons (left and right) for navigation.
1. Are you still using these buttons in your game/app?
2. Are you you also supporting a swipe functionality?

I will assume that the answers to questions #1 and #2 are “Yes” and that you want two pushbuttons and a swipe function that do similar things.

With the above assumption in mind, you need to do a few things.

  1. Forget about dispatch. I think you’ll be better off with direct function calls.

  2. Make copies of your original code and set that code aside.

  3. Gut your original callback(s) for left and right button pushes. That is remove all of the code that does utility work like updating your game logic, creating/destroying/modifying display objects, etc.

  4. Take the utility code you removed and put it one or more new utility functions. It is OK to pass the event table to these functions if they need something from the table to do their work.

  5. Take the gutted callback(s) from step #2 and insert calls to your utility code from step #3.

  6. Substitute the new callback(s) for your old callback(s).

  7. Test the changes and be sure you didn’t break anything.

  8. Write a new callback for the swipe event. This callback should only make decisions about the swipe. In the appropriate places, call the extracted utility code from step #3.

  9. Hook up your new swipe callback and test it out.

The following is a purely hypothetical example of what I just layed out in the steps above.

My hypothetical original button code

left\_touch = function( event )  
  
 if event.phase == "began" then  
  
 -- LEFT WORK A  
  
 elseif event.phase == "moved" then  
  
 -- LEFT WORK B  
  
 elseif event.phase == "ended" or event.phase == "cancelled" then  
  
 -- LEFT WORK C  
  
 end  
  
 -- LEFT WORK D  
  
end  
  
leftButton:addEventListener("touch",left\_touch)  
  
-- Assume similar for right button  
  

My gutted and modified button code

-- Note: Following functions can have more arguments if you need them  
left\_workA = function(event)   
 -- LEFT WORK A  
end  
  
left\_workB = function(event)  
 -- LEFT WORK B  
end  
  
left\_workC = function(event)  
 -- LEFT WORK C  
end  
  
left\_workD = function(event)  
 -- LEFT WORK D  
end  
new\_left\_touch = function( event )  
  
 if event.phase == "began" then  
 left\_workA( event )  
  
 elseif event.phase == "moved" then  
 left\_workB( event )  
  
 elseif event.phase == "ended" or event.phase == "cancelled" then  
 left\_workC( event )  
  
 end  
  
 left\_workD( event )  
end  
leftButton:addEventListener("touch",new\_left\_touch)  
  
-- Assume similar for right button  

My hypothetical swipe code

scrollMe = function (event)  
  
 if event.phase == "began" then  
  
 if( ??? is left swipe ??? ) then  
 left\_workA( event )  
 else  
 right\_workA( event )  
 end  
 elseif event.phase == "moved" then  
  
 if( ??? is left swipe ??? ) then  
 left\_workB( event )  
 else  
 right\_workB( event )  
 end  
  
 elseif event.phase == "ended" or event.phase == "cancelled" then  
  
 if( ??? is left swipe ??? ) then  
 left\_workC( event )  
 else  
 right\_workC( event )  
 end  
  
 end  
  
 left\_workD( event )  
 right\_workD( event )  
end  
  
swipeArea:addEventListener("touch",scrollMe)  

I hope this helps. I know getting your head around touch inputs is challenging, especially when you introduce intermediate inputs like swiping. Just keep working at it. I know you’ll eventually crack this nut.

Cheers,
Ed
Roaming Gamer, LLC.
SSK for Corona SDK (github) (videos)
[import]uid: 110228 topic_id: 31894 reply_id: 127728[/import]

Sorry, I am not getting emails either? I will look into your suggestion!

Thanks, Joakim [import]uid: 81188 topic_id: 31894 reply_id: 127821[/import]