@Aidin,
to answer your original question, yes, custom events can be dispatched within other event handlers. dispatchEvent()
can be called at any time. if the system is already doing something, then any new events will be placed on a stack to be handled at some later point.
for your second round of questions, why don’t certain setups work and others don’t:
#1
your first example doesn’t work because the code you have written is expecting something like a broadcast system that objects can tie into when they want.
an analogy for this might be like students in a school building listening to messages come across the intercom system. in this case your ‘listener’ is a student and ‘caller’ is someone making an announcement. you can’t see the intercom, but can hear it, so it’s like a magical communication system which links ‘caller’ to ‘listener’.
this type of communication doesn’t exist in Corona and never will unless you implement it yourself. this is because this type of functionality isn’t a core part of Lua or Corona. (the only language i know of which has something similar to this is Erlang.)
#2
your second example works because you’re using the event system how it was intended. however, you have essentially linked ‘listener’ to ‘listener’ and you would never really do this in practice.
(though, because you’re partially using objects and partially using function callbacks, it’s a little hard to tell exactly what you’re trying to accomplish. i can only surmise that the function myListener() is related to the object ‘listener’)
the Event System
the event system setup is always about two separate things, one of them wants to know something about the other, and communication always flows in a single direction. for example, a teacher asks a student to tell them when the student has finished their quiz.
if the teacher wants to know about all students, then the teacher must ask *each individual* student for notification. in short, the event system is 1-to-1 even though more than one object can listen for the same event (making it 1-to-N or N-to-1). but you ALWAYS have to setup 1-to-1 communication using addEventListener(). no exceptions.
1-to-N
all students ask teacher to tell them about any homework assignment
student (N) << notification << teacher (1)
N-to-1
teacher asks all students to tell when done with quiz
teacher (1) << notification << student (N)
addEventListener()
before we get into some code, let’s break down the addEventListener() call. i think this will help to make sure you get things hooked up correctly. but let me change the variable names to give clarity:
[lua]eventSender:addEventListener( “senderSaysThis”, eventReceiver )[/lua]
even though ‘eventSender’ seems like the main actor here, the communication is “initiated” by ‘eventReceiver’. you see, ‘eventSender’ can send out messages whenever it wants, even if no one is listening. but the key driver for putting this in your code is that ‘eventReceiver’ wants to know about a certain message from the sender.
putting it in context of our school example, this is what the call would look like:
[lua]student:addEventListener( “done_with_quiz”, teacher )[/lua]
the student object is at the front of the call, but we know that it’s really the teacher asking for notification about the completed quiz.
here is an example which shows the direction of communication. communication is setup to go from blue to red. red is notified when blue is tapped.
[lua]
local redBtn = display.newRect( 90, 100, 150, 60 )
redBtn:setFillColor( 250, 50, 50 )
function redBtn:tap( e )
print(“Notify red button”)
end
local blueBtn = display.newRect(90, 250, 150, 60 )
blueBtn:setFillColor( 90, 90, 250 )
function blueBtn:tap( e )
print(“Notify blue button”)
end
blueBtn:addEventListener( ‘tap’, redBtn )
– =======================
– Output
Notify red button
[/lua]
dispatchEvent()
an important point to keep in mind is it will ALWAYS be the ‘eventSender’ that will call dispatchEvent(), and ‘eventReceiver’ is going to get the event.
[lua]student:dispatchEvent( “done_with_quiz” )[/lua]
Code Review
so now, given all of that, we can review your examples and clearly see what was happening. 
#1
this one doesn’t work because ‘listener’ and ‘caller’ aren’t even hooked up. so when ‘caller’ dispatches the event, no one is listening.
#2
this one works, but as i mentioned before, the ‘listener’ has (seemingly) asked itself to give itself notification. this isn’t very effective and certainly not what you want.
here is your example re-written in a more OO, clear, concise manner.
[lua]
local listener = display.newRect(100,100,100,100)
local caller = display.newRect(200,200,200,200)
– we create an object method because we have two objects communicating
function listener:myEventType( event )
print( "Event " … event.name )
end
– let’s setup communication, listener << notification << caller
caller:addEventListener( “myEventType”, listener )
– caller says something
caller:dispatchEvent( { name=“myEventType” } )
– =======================
– Output
Event myEventType
[/lua]
A solution
here’s a solution which gives you a communication system closer to what you were initially trying to do. you will still have to setup at least one addEventListener() call to the “megaphone”, but that’s it. after that, every object can broadcast to every other object without additional calls to addEventListener().
as @SegaBoy said, he uses the Runtime object as a global dispatcher. my preference would be to just create a separate global object (e.g., a displayGroup) to do this. a displayGroup is preferable because 1. like the Runtime it doesn’t have any visual components, 2. you’re not “hacking” the Runtime object which already has a role to play in the system, 3. you can make as many as you want for different purposes (eg, “private” megaphones for different classes).
[lua]
–
– main.lua
– this is our global megaphone
– all objects are going to listen and speak using this
gMegaphone = display.newGroup()
– setup global string for our event
BCAST = “broadcastEvent”
– setup red object
local red = display.newRect( 90, 100, 150, 60 )
red:setFillColor( 250, 50, 50 )
– here we’re setting up *listening*
gMegaphone:addEventListener( BCAST, red )
– this is our broadcast event handler
function red:broadcastEvent( event )
– we don’t want to process messages we’ve sent
if event.sender == self then return end
print( “Red Broadcast Event” )
print( "Event msg: " … event.message … “\n” )
end
function red:say( message )
local e = {
name = BCAST,
message = message,
sender = self
}
– here we’re using the global megaphone to speak
gMegaphone:dispatchEvent( e )
end
– setup blue object
local blue = display.newRect( 90, 250, 150, 60 )
blue:setFillColor( 90, 90, 250 )
– here we’re setting up *listening*
gMegaphone:addEventListener( BCAST, blue )
– this is our broadcast event handler
function blue:broadcastEvent( event )
– we don’t want to process messages we’ve sent
if event.sender == self then return end
print( “Blue Broadcast Event” )
print( "Event msg: " … event.message … “\n” )
end
function blue:say( message )
local e = {
name = BCAST,
message = message,
sender = self
}
– here we’re using the global megaphone to speak
gMegaphone:dispatchEvent( e )
end
blue:say( “hello from blue” )
red:say( “hello from red” )
– =============
– output:
– the main thing to see here is that Red and Blue are communicating
– however, neither of them made a addEventListener() call to the other !!!
– eg, blue:addEventListener( BCAST, red )
– it was only necessary to setup communication using the “megaphone”
Red Broadcast Event
Event msg: hello from blue
Blue Broadcast Event
Event msg: hello from red
[/lua]
i hope that helps to understand how to hook up event communication and give you a better solution to handle object communication in your app.
cheers,
dmc
[import]uid: 74908 topic_id: 36332 reply_id: 144392[/import]