Module: EF::Object

Defined in:
lib/event-framework.rb

Overview

provides methods for publish–subscribe pattern

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object

allows you to extend any object

obj = Object.new
obj.extend EF::Object


133
134
135
136
137
138
# File 'lib/event-framework.rb', line 133

def self.extended(base)
  base.instance_variable_set :@mutex, Mutex.new
  base.instance_variable_set :@thread, Thread.current
  base.instance_variable_set :@observers, []
  base.instance_variable_set :@observables, []
end

.included(base) ⇒ Object

patches initialize to admix needed variables



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/event-framework.rb', line 106

def self.included(base)
  return if base.respond_to? :ef

  def base.ef; end

  base.class_exec do
    alias alias_initialize initialize

    ##
    # defines needed variables and calls original initialize
    def initialize(*args, &block)
      alias_initialize *args, &block

      @mutex = Mutex.new

      @thread = Thread.current

      @observers = []
      @observables = []
    end
  end
end

Instance Method Details

#listen_to(observable, event, &block) ⇒ Object

registrate a handler for the event



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/event-framework.rb', line 170

def listen_to(observable, event, &block)
  raise 'observable is not EF::Object' unless observable.is_a? Object
  raise 'event is not string' unless event.is_a? String
  raise 'block not given' unless block_given?

  @mutex.synchronize do
    @observables << [observable, event, block]

    if self == observable
      @observers << [self, event, block]
    else
      observable.registrate(self, event, block)
    end
  end
end

#move_to(thread) ⇒ Object

by default handlers will be executed in the thread where the receiver was defined
the method changes it so that handlers will be executed in the passed thread



228
229
230
231
232
# File 'lib/event-framework.rb', line 228

def move_to(thread)
  @mutex.synchronize do
    @thread = thread
  end
end

#off(event = nil, block = nil) ⇒ Object

stop listening to self



221
222
223
# File 'lib/event-framework.rb', line 221

def off(event=nil, block=nil)
  stop_listening self, event, block
end

#on(event, &block) ⇒ Object

listen to self



188
189
190
191
192
193
# File 'lib/event-framework.rb', line 188

def on(event, &block)
  raise 'event is not string' unless event.is_a? String
  raise 'block not given' unless block_given?

  listen_to self, event, &block
end

#stop_listening(observable = nil, event = nil, block = nil) ⇒ Object

unregistrate all matching handlers



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/event-framework.rb', line 197

def stop_listening(observable=nil, event=nil, block=nil)
  @mutex.synchronize do
    observables = []

    @observables.each do |o, e, b|
      if (!observable || o == observable) && (!event || e == event) && (!block || b == block)
        if self == o
          @observers.reject! do |o, e, b|
            o == self
          end
        else
          o.unregistrate(self, e, b)
        end
      else
        observables << [o, e, b]
      end
    end

    @observables = observables
  end
end

#threadObject

returns the thread where the object was defined



142
143
144
# File 'lib/event-framework.rb', line 142

def thread
  @thread
end

#trigger(event, *args) ⇒ Object

calls handlers for observers for the event
parameters and the caller will be passed to the handlers
notice: usually in threads of sibscribers



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/event-framework.rb', line 150

def trigger(event, *args)
  raise 'event is not string' unless event.is_a? String

  @mutex.synchronize do
    @observers.each do |o, e, b|
      if e == event
        if Thread.instances.include? o.thread
          o.thread.add self, *args, &b
        elsif Loop.thread
          Loop.thread.add self, *args, &b
        else
          b.call self, *args
        end
      end
    end
  end
end