Module: RubyMVC::Toolkit::SignalHandler

Included in:
Models::Model, AbstractWidget, PropertyChangeNotifier, WxRuby::Dialog, WxRuby::Frame, WxRuby::GridView, WxRuby::WebView
Defined in:
lib/ruby_mvc/toolkit/signal_handler.rb

Overview

This module provides an implementation of signal handlers originally modelled on the GTK+ 2.x mechanisms. While it is similar to GTK+, it may not behave in exactly the same way.

This module also defines some useful class methods to expand the meta-programming of Ruby objects to support signal handling. To use these methods, you follow the following idiom in the derived class:

class SignalSource
  incude RubyMVC::Toolkit::SignalHandler
  extend RubyMVC::Toolkit::SignalHandler::ClassMethods
  ...
end

Once the class has been defined as per above, valid signals for the signal source may be defined using the class method #signal as follows:

class SignalSource
  ...

  signal "sig1", :description => "A test signal", 
  signal "sig2", :description => "A vetoable signal", :vetoable => true
  ...
end

To register for signal notification, use the #signal_connect method of the signal source instance as follows:

src = SignalSource.new
src.signal_connect "sig1" do |sender|
  ...
end

Internally to the signal source instance, the signal can be triggered using the #signal_emit method as follows

class SignalSource
  def send_sig1
    ...
    signal_emit("sig1", self)
    ...
  end
end

Planned Areas of Improvement

Currently, there’s not a really good way to document the signals so that they’re clear. I’m not sure how these are represented in rdoc, but there should be a method/way to specify the arguments in order and what they should be so that they live with the signal definition within the class itself so things are self-documenting.

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#signal_connect(signal, &block) ⇒ Object



123
124
125
126
127
128
129
130
# File 'lib/ruby_mvc/toolkit/signal_handler.rb', line 123

def signal_connect(signal, &block)
  self.class.valid_signal! signal if self.class.respond_to? :signals
  signals = (@signals ||= {})
  sigs = (signals[signal] ||= [])
  if !sigs.include? block
    sigs << block
  end
end

#signal_disconnect(signal, &block) ⇒ Object



132
133
134
135
136
137
# File 'lib/ruby_mvc/toolkit/signal_handler.rb', line 132

def signal_disconnect(signal, &block)
  self.class.valid_signal! signal if self.class.respond_to? :signals
  signals = (@signals ||= {})
  sigs = (signals[signal] ||= [])
  sigs.delete(block)
end

#signal_emit(signal, *args) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/ruby_mvc/toolkit/signal_handler.rb', line 139

def signal_emit(signal, *args)
  # FIXME: there's a few things wrong with this now that
  # we've changed to support multiple signal handlers.
  # Registration/deregistration should be cleaner, but
  # then we'd be using an observer pattern vs the signal
  # handler.  Anyway, with multiple registered handlers,
  # if the signal is vetoable, then it should throw a veto
  # exception or something.

  self.class.valid_signal! signal if self.class.respond_to? :signals
  signals = (@signals ||= {})
  rval = nil
  (signals[signal] ||= []).each do |proc|
    (rval = proc.call(*args)) if !proc.nil?
  end
  rval
end