#
# dispatch.rb
#
#   Copyright (c) 1999 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
#
#
# usage:
#
#   class Handler
#
#     include Dispatchable
#
#     event_handler :on_click
#
#     def clicked( event )
#       do_my_click_work()
#       dispatch :on_click, event  # call handler with 1 arg
#     end
#
#   end
#


module Dispatchable

  def Dispatchable.append_features( mod )

    super   # don't forget

    def mod.event_handler( sim )
      name = sim.id2name
      str = %-
        def #{name}( &blk )
          unless blk then
            raise NameError,
              "evant register was called without block"
          end
          push_event( :#{name}, blk )
        end
      -
      module_eval str
    end
  end


  def push_event( sim, blk )
    unless @dispatch_table then
      @dispatch_table = {}
    end
    unless arr = @dispatch_table[ sim ] then
      @dispatch_table[ sim ] = arr = []
    end
    arr.push blk
  end


  def pop_event( sim )
    if tbl = @dispatch_table then
      if arr = tbl[ sim ] then
        arr.pop
      end
    end
  end


  def dispatch( sim, *args )
    unless @dispatch_table then
      @dispatch_table = nil
      return
    end
    arr = @dispatch_table[ sim ]
    if arr and arr.size > 0 then
      arr.each {|blk| blk.call( self, *args ) }
    end
  end

end
