Class: Flexo::Dispatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/flexo/dispatcher.rb

Overview

Dispatcher receives data from Flexo::Server, analyzes it, and creates relevant events (see Flexo::Event), which is then broadcast to all classes and plugins wanting to use it for something.

This class also manages subscriptions for events, so all plugins that want to listen for an event, can use subscribe and unsubscribe to manage things.

Instance Method Summary collapse

Constructor Details

#initializeDispatcher

Save a reference to Flexo::Manager, set up the dispatching-queue, and get ready for working.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/flexo/dispatcher.rb', line 27

def initialize
  @manager  = Flexo::Manager.instance
  @queue    = Queue.new
  @handlers = {}
  @triggers = []

  @manager.thread do 
    while event = @queue.shift
      next unless @handlers.key?(event.class)
      @handlers[event.class].each { |h| 
        @manager.logger.debug2("Running handler #{h} for #{event.class}")
        h.call(event) 
      }
    end
  end
end

Instance Method Details

#add_trigger(pattern, &block) ⇒ Object

Easy way to add a trigger. See Flexo::Trigger for documentation



132
133
134
135
136
137
# File 'lib/flexo/dispatcher.rb', line 132

def add_trigger(pattern, &block)
  trigger = Flexo::Trigger.new(pattern, &block)
  @manager.mutex { @triggers << trigger }
  
  return trigger
end

#await(event, opts = {}, &block) ⇒ Object

Waits for a specified amount of time, which defaults to 60. If the chosen event isn’t receieved within that time, a TimeoutError is raised.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/flexo/dispatcher.rb', line 115

def await(event, opts = {}, &block)
  opts    = {:timeout => 60}.merge(opts)
  queue   = Queue.new
  handler = subscribe(event) do |e|
    queue << e
    block.call(e) if block_given?
  end

  begin
    Timeout.timeout(opts[:timeout], Flexo::TimeoutError) { queue.shift }
  ensure
    unsubscribe(handler)
  end
end

#receive(line) ⇒ Object

Does the handling of incoming lines. First, we use Flexo::Data to get anything meaningful out of the line received. Then, we create a subclass of Flexo::Event, which is pushed onto the dispatching-queue for further processing.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/flexo/dispatcher.rb', line 49

def receive(line)
  @manager.logger.debug2("Received \"#{line.chomp}\"")
  data  = Data.new(line)
  event = case data.message
  when /^\d+$/   then Flexo::Events::ReplyEvent.new   @manager, data
  when 'JOIN'    then Flexo::Events::JoinEvent.new    @manager, data
  when 'KICK'    then Flexo::Events::KickEvent.new    @manager, data
  when 'MODE'    then Flexo::Events::ModeEvent.new    @manager, data
  when 'NICK'    then Flexo::Events::NickEvent.new    @manager, data
  when 'NOTICE'  then Flexo::Events::NoticeEvent.new  @manager, data
  when 'PART'    then Flexo::Events::PartEvent.new    @manager, data
  when 'PING'    then Flexo::Events::PingEvent.new    @manager, data
  when 'PONG'    then Flexo::Events::PongEvent.new    @manager, data
  when 'PRIVMSG' then Flexo::Events::PrivmsgEvent.new @manager, data
  when 'QUIT'    then Flexo::Events::QuitEvent.new    @manager, data
  when 'TOPIC'   then Flexo::Events::TopicEvent.new   @manager, data
  else                Flexo::Events::UnknownEvent.new @manager, data
  end

  @queue << event
end

#remove_trigger(trigger) ⇒ Object

Easy way to remove a trigger. Must be passed a Flexo::Trigger object



141
142
143
144
# File 'lib/flexo/dispatcher.rb', line 141

def remove_trigger(trigger)
  trigger.unsubscribe
  @manager.mutex { @triggers.delete(trigger) }
end

#subscribe(event, &block) ⇒ Object

Registers a callback function for a specific event.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/flexo/dispatcher.rb', line 72

def subscribe(event, &block)
  if event.is_a?(Symbol) || event.kind_of?(String)
    if (e = event.to_s) =~ /^(?:RPL|ERR)_/i
      @manager.logger.debug "Subscribing to a ReplyEvent (#{e})"
      event = Flexo::Events::ReplyEvent[e.upcase]
    else
      match = e.match(/^(.+?)(?:_?event)?$/i)
      event = Flexo::Events.const_get("#{match[1].capitalize}Event")
      @manager.logger.debug "Subscribing to a #{match[1].capitalize}Event (else)"
    end
  end

  if event.is_a? Flexo::Events::ReplyEvent::Numeric
    numeric = event.numeric
    event   = Flexo::Events::ReplyEvent
  else
    numeric = false
  end

  @manager.logger.debug "Creating a handler against #{numeric.to_s}"
  handler = Handler.new(numeric, &block)
  @manager.mutex do
    @handlers[event] ||= []
    @handlers[event] << handler
  end

  return handler
end

#unsubscribe(handler) ⇒ Object

Removes an event handler.



102
103
104
105
106
107
108
109
110
# File 'lib/flexo/dispatcher.rb', line 102

def unsubscribe(handler)
  @manager.logger.debug("Going to remove handler #{handler}")
  
  @handlers.each do |event,handlers|
    handlers.delete handler
  end
  
  @manager.logger.debug("Handler #{handler} removed")
end