Event Dispatcher

One easy way for your script to gain event dis­patch­ing capa­bil­i­ties is to inher­it the “Event­Dis­patch­er” script.
For exam­ple, this is your but­ton behaviour:

Show code

– But­ton behav­iour script
prop­er­ty ancestor
prop­er­ty myType
prop­er­ty myID

on begin­Sprite( me )
ances­tor = script( “Event­Dis­patch­er” ).rawNew()
callAnces­tor( #new, me, me )
myType = #push­But­ton
sprite( me.spritenum ).cur­sor = 280
me.dispatchEvent( #but­ton­Ready, [ #id:myID ] )
end beginSprite

on mouse­Up( me )
me.dispatchEvent( #but­tonClick, [#type:myType, #id:myID] )
end mouseUp

on get­Prop­er­ty­De­scrip­tion­List( me )
pdl = propList()
pdl.addProp( #myID, [ #format:#symbol, #default: sym­bol( “button”&_player.currentSpritenum ), #comment:“WidgetID:” ] )
return pdl
end getPropertyDescriptionList


And this is your ColourPick­er behaviour:
Show code

– ColourPick­er behav­iour script
prop­er­ty ancestor
prop­er­ty myID
prop­er­ty myType
prop­er­ty mySprite
prop­er­ty myColor

on begin­Sprite( me )
ances­tor = script( “Event­Dis­patch­er” ).rawNew()
callAnces­tor( #new, me, me )
mySprite = sprite( me.spritenum )
myCol­or = me.randomColor()
mySprite.color = myColor
myType = #col­or­Pick­er
sprite( me.spritenum ).cur­sor = 280
me.dispatchEvent( #col­or­Ready, [#id:myID, #color:myColor] )
end beginSprite

on mouse­Up( me )
myCol­or = me.randomColor()
mySprite.color = myColor
me.dispatchEvent( #col­or­Change,[ #type:myType, #id:myID, #color:myColor ] )
end mouseUp

on ran­dom­Col­or( me )
r = ran­dom( 64, 225 )
g = ran­dom( 64, 190 )
b = ran­dom( 64, 128 )
return( col­or( r, g, b ) )
end randomColor

on get­Prop­er­ty­De­scrip­tion­List( me )
pdl = propList()
pdl.addProp( #myID, [ #format:#symbol, #default: sym­bol( “color”&_player.currentSpritenum ), #comment:“WidgetID:” ] )
return pdl
end getPropertyDescriptionList


Now, you can com­bine all of the appli­ca­tion “log­ic” in one place:
Show code

– Main Frame Script
prop­er­ty display

on begin­Sprite( me )
_movie.puppetTempo( 90 )
dis­play = sprite( “DISPLAY” ).mem­ber
display.text = EMPTY
end beginSprite

on exit­Frame( me )
_movie.go( _movie.frame )
end exitFrame

on but­ton­Ready( me, event )
event.sender.addEventListener( #but­tonClick, #dis­play, me )
end buttonReady

on col­or­Ready( me, event )
event.sender.addEventListener( #col­or­Change, #dis­play, me )
end colorReady

– Appli­ca­tion “log­ic”
on dis­play( me, event )
args = event.args
case( args.type ) of
#push­But­ton :
case( args.id ) of
#button1: msg = “FIRST BUTTON WAS CLICKED
#button2: msg = “SECOND BUTTON WAS CLICKED
#button3: msg = “THIRD BUTTON WAS CLICKED
end case
display.color = col­or( 0,0,0 )
display.text = string( msg )
#col­or­Pick­er:
_title = “The colour in _ was changed to” && args.color
case( args.id ) of
#color1: cp = “COLOURPICKER1
#color2: cp = “COLOURPICKER2
end case
x = off­set( “_”, _title )
put cp into char x of _title
x = off­set( “col­or(“, _title )
display.text = string( _title )
display.char[ x..(_title.length) ].col­or = args.color
end case
end display


The “Event­Dis­patch­er” script is list­ed below:
Show code

– Event­Dis­patch­er par­ent script
— Author: Vladin M. Mitov
— Octo­ber, 2010
— Last update — May, 2012
— http://www.ed-multimedia.com

– addE­ventLis­ten­er( Sym­bol­Event­Name, Sym­bol­Call­back­Method, ObjectListener )
— removeEventLis­ten­er( ObjectLis­ten­er, Sym­bol­Event­Name, SymbolCallbackMethod )
— hasEv­entLis­ten­ers( Sym­bol­Event­Name ) : #Boolean
— removeAllEventListeners()
— dis­patchEvent( Sym­bol­Event­Name, [ args ] )
— stopEvent()
— events( me ) : #List with reg­is­tered events

————————————————-
FIELDS
————————————————-
on ___________________________PROPERTIES
end

prop­er­ty successor
prop­er­ty _listeners
prop­er­ty _temp
————————————————-
CONSTRUCTOR
————————————————-
on ___________________________CONSTRUCTOR
end
on new( me, s )
if( voidP( s ) ) then
suc­ces­sor = me
else
suc­ces­sor = s
end if
_listeners = propList()
_temp = propList()
return me
end new

————————————————-
PUBLIC METHODS
————————————————-
on ___________________________PUBLIC_METHODS
end

on dis­pose( me )
suc­ces­sor = VOID
if ( _listeners.ilk = #pro­pList ) then
repeat with i in _listeners
i.deleteAll()
end repeat
end if
end dispose

on addE­ventLis­ten­er( me, aevent­Name, acall­back­Method, alistener )
case ( alistener.ilk ) of
#instance, #sprite, #_movie, #win­dow:
if ( _listeners.findPos (aevent­Name ) = 0 ) then
_listeners.addprop( aeventName, [ : ] )
end if
if ( voidP( _listeners[ aevent­Name ].find­Pos( acall­back­Method ) ) ) then
_listeners[ aevent­Name ].addProp( acall­back­Method, list() )
end if
if ( _listeners[ aevent­Name ][ acall­back­Method ].get­Pos( alis­ten­er ) = 0 ) then
_listeners[ aevent­Name ][ acall­back­Method ].append( alistener )
end if
otherwise:
me._exception( “Invalid lis­ten­er type:” && ilk( alis­ten­er ) & RETURN & \
“A lis­ten­er type must be”& RETURN & “#instance, #sprite, #_movie or #win­dow.” )
abort
end case
end addEventListener

on removeEventLis­ten­er( me, alis­ten­er, aEvent­Name, acallbackMethod )
ecnt = count( _listeners )
repeat with e = ecnt down to 1
if( aEvent­Name = _listeners.getPropAt( e ) ) then
event = _listeners[ e ]
ccnt = event.count
repeat with c = ccnt down to 1
call­back = event.getPropAt( c )
if( acall­back­Method = call­back ) then
objects = event[ c ]
ocnt = count( objects )
repeat with l = ocnt down to 1
if( alis­ten­er = objects[ l ].lis­ten­er ) then
objects.deleteAt( l )
end if
end repeat
if( count( objects ) = 0 ) then
event.deleteProp( callback )
end if
end if
end repeat
if( count( event ) = 0 ) then
_listeners.deleteProp( aEventName )
end if
end if
end repeat
end removeListener

on hasEv­entLis­ten­ers( me, aEventName )
return not voidP( _listeners.findPos( aEventName ) )
end hasEventListeners

on removeAl­lEventLis­ten­ers( me )
cnt = count( _listeners )
repeat with i = cnt down to 1
_listeners[ i ].deleteAll()
end repeat
_listeners.deleteAll()
end removeAllEventListeners

on dis­patchEvent( me, aevent­Name, args )
if voidP( _listeners.findPos( aevent­Name ) ) then
sendAll­Sprites( aevent­Name, [ #sender:successor, #args:args ] )
return
end if
_temp = _listeners[ aevent­Name ].dupli­cate()
cnt = count( _temp )
repeat with i = cnt down to 1
call­back = _temp.getPropAt( i )
receivers = _temp[ i ]
call( call­back, receivers, [ #type:aeventName, #sender:successor, #args:args ] )
end repeat
end dispatchEvent

on stopEvent( me )
receivers = _temp[ 1 ]
cnt = count( receivers )
receivers.deleteAll()
end stopEvent

on events( me )
t = list()
repeat with i = 1 to count( _listeners )
t.append( _listeners.getPropAt( i ) )
end repeat
return t
end events

on inter­face( me )
msg = EMPTY
put “addE­ventLis­ten­er( Sym­bol­Event­Name, Sym­bol­Call­back­Method, ObjectLis­ten­er, { para­me­terList } )” & RETURN after msg
put “removeEventLis­ten­er( ObjectLis­ten­er, Sym­bol­Event­Name, Sym­bol­Call­back­Method )” & RETURN after msg
put “hasEv­entLis­ten­ers( Sym­bol­Event­Name )” & RETURN after msg
put “removeAl­lEventLis­ten­ers()” & RETURN after msg
put “dis­patchEvent( Sym­bol­Event­Name, Object­Sender, { args } )” & RETURN after msg
put “stopEvent()” & RETURN after msg
put “events( me ) — Returns a list with reg­is­tered events.” after msg
return msg
end interface

————————————————-
PRIVATE METHODS
————————————————-
on ___________________________PRIVATE_METHODS
end

on _exception( me, msg )
_player.alert( msg )
_movie.halt() — place a break­point here
end _exception

Event Dis­patch­er demo
Event Dis­patch­er (7829 downloads) 
 
Comments

Added / updat­ed the fol­low­ing methods:

hasEv­entLis­ten­ers( SymbolEventName )
dis­patchEvent( Sym­bol­Event­Name, PropListOfArguments )

Added stopEvent() method.

Exam­ple:

on even­tHandler( event )
if( con­di­tion = true ) then
event.sender.stopEvent()
end if
end eventHandler