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
-- Button behaviour script
property ancestor
property myType
property myID

on beginSprite( me )
  ancestor = script( "EventDispatcher" ).rawNew()
  callAncestor( #new, me, me )
  myType = #pushButton
  sprite( me.spritenum ).cursor = 280
  me.dispatchEvent( #buttonReady, [ #id:myID ] )
end beginSprite

on mouseUp( me )
  me.dispatchEvent( #buttonClick, [#type:myType, #id:myID] )
end mouseUp

on getPropertyDescriptionList( me )
  pdl = propList()
  pdl.addProp( #myID, [ #format:#symbol, #default: symbol( "button"&_player.currentSpritenum ), #comment:"WidgetID:" ] )
  return pdl
end getPropertyDescriptionList


And this is your ColourPick­er behaviour:
Show code
-- ColourPicker behaviour script
property ancestor
property myID
property myType
property mySprite
property myColor

on beginSprite( me )
  ancestor = script( "EventDispatcher" ).rawNew()
  callAncestor( #new, me, me )
  mySprite = sprite( me.spritenum )
  myColor = me.randomColor()
  mySprite.color = myColor
  myType = #colorPicker
  sprite( me.spritenum ).cursor = 280
  me.dispatchEvent( #colorReady, [#id:myID, #color:myColor] )
end beginSprite

on mouseUp( me )
  myColor = me.randomColor()
  mySprite.color = myColor
  me.dispatchEvent( #colorChange,[ #type:myType, #id:myID, #color:myColor ]  )
end mouseUp

on randomColor( me )
  r = random( 64, 225 )
  g = random( 64, 190 )
  b = random( 64, 128 )
  return( color( r, g, b ) )
end randomColor

on getPropertyDescriptionList( me )
  pdl = propList()
  pdl.addProp( #myID, [ #format:#symbol, #default: symbol( "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
property display

on beginSprite( me )
  _movie.puppetTempo( 90 )
  display = sprite( "DISPLAY" ).member
  display.text = EMPTY
end beginSprite

on exitFrame( me )
  _movie.go( _movie.frame )
end exitFrame

on buttonReady( me, event )
  event.sender.addEventListener( #buttonClick, #display, me )
end buttonReady

on colorReady( me, event )
  event.sender.addEventListener( #colorChange, #display, me )
end colorReady

-- Application "logic"
on display( me, event )
  args = event.args
  case( args.type ) of
    #pushButton :
      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 = color( 0,0,0 )
      display.text = string( msg )
    #colorPicker:
      _title = "The colour in _ was changed to" && args.color
      case( args.id ) of
        #color1: cp = "COLOURPICKER1"
        #color2: cp = "COLOURPICKER2"
      end case
      x = offset( "_", _title )
      put cp into char x of _title
      x = offset( "color(", _title )
      display.text = string( _title )
      display.char[ x..(_title.length) ].color = args.color
  end case
end display


The “Event­Dis­patch­er” script is list­ed below:
Show code
-- EventDispatcher parent script
-- Author: Vladin M. Mitov
-- October, 2010
-- Last update - May, 2012
-- http://www.ed-multimedia.com

-- addEventListener( SymbolEventName, SymbolCallbackMethod, ObjectListener )
-- removeEventListener( ObjectListener, SymbolEventName, SymbolCallbackMethod )
-- hasEventListeners( SymbolEventName ) : #Boolean
-- removeAllEventListeners()
-- dispatchEvent( SymbolEventName, [ args ] )
-- stopEvent()
-- events( me ) : #List with registered events

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

property successor
property _listeners
property _temp
-------------------------------------------------
-- CONSTRUCTOR
-------------------------------------------------
on ___________________________CONSTRUCTOR
end
on new( me, s )
  if( voidP( s ) ) then
    successor  = me
  else
    successor  = s
  end if
  _listeners = propList()
  _temp = propList()
  return me
end new

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

on dispose( me )
  successor = VOID
  if ( _listeners.ilk = #propList ) then
    repeat with i in _listeners
      i.deleteAll()
    end repeat
  end if
end dispose

on addEventListener( me, aeventName, acallbackMethod, alistener )
  case ( alistener.ilk ) of
    #instance, #sprite, #_movie, #window:
      if ( _listeners.findPos (aeventName ) = 0 ) then
        _listeners.addprop( aeventName, [ : ] )
      end if
      if ( voidP( _listeners[ aeventName ].findPos( acallbackMethod ) ) ) then
        _listeners[ aeventName ].addProp( acallbackMethod, list() )
      end if
      if ( _listeners[ aeventName ][ acallbackMethod ].getPos( alistener ) = 0 ) then
        _listeners[ aeventName ][ acallbackMethod ].append( alistener )
      end if
    otherwise:
      me._exception( "Invalid listener type:" && ilk( alistener ) & RETURN & \
      "A listener type must be"& RETURN & "#instance, #sprite, #_movie or #window." )
      abort
  end case
end addEventListener

on removeEventListener( me, alistener, aEventName, acallbackMethod )
  ecnt = count( _listeners )
  repeat with e = ecnt down to 1
    if( aEventName = _listeners.getPropAt( e ) ) then
      event = _listeners[ e ]
      ccnt = event.count
      repeat with c = ccnt down to 1
        callback = event.getPropAt( c )
        if( acallbackMethod = callback ) then
          objects = event[ c ]
          ocnt = count( objects )
          repeat with l = ocnt down to 1
            if( alistener = objects[ l ].listener ) 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 hasEventListeners( me, aEventName )
  return not voidP( _listeners.findPos( aEventName ) )
end hasEventListeners

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

on dispatchEvent( me, aeventName, args )
  if voidP( _listeners.findPos( aeventName ) ) then
    sendAllSprites( aeventName, [ #sender:successor, #args:args ] )
    return
  end if
  _temp = _listeners[ aeventName ].duplicate()
  cnt = count( _temp )
  repeat with i = cnt down to 1
    callback = _temp.getPropAt( i )
    receivers = _temp[ i ]
    call( callback, 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 interface( me )
  msg = EMPTY
  put "addEventListener( SymbolEventName, SymbolCallbackMethod, ObjectListener, { parameterList } )" & RETURN after msg
  put "removeEventListener( ObjectListener, SymbolEventName, SymbolCallbackMethod )" & RETURN after msg
  put "hasEventListeners( SymbolEventName )" & RETURN after msg
  put "removeAllEventListeners()" & RETURN after msg
  put "dispatchEvent( SymbolEventName, ObjectSender, { args } )" & RETURN after msg
  put "stopEvent()" & RETURN after msg
  put "events( me ) - Returns a list with registered events." after msg
  return msg
end interface

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

on _exception( me, msg )
  _player.alert( msg )
  _movie.halt() -- place a breakpoint here
end _exception

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

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

hasEventListeners( SymbolEventName )
dispatchEvent( SymbolEventName, PropListOfArguments )

Added stopEvent() method.

Exam­ple:

on eventHandler( event )
  if(  condition = true ) then
    event.sender.stopEvent()
  end if
end eventHandler