Skip to content

Commit

Permalink
Allow subscribing of listener(s) for the duration of a block [8]
Browse files Browse the repository at this point in the history
  • Loading branch information
krisleech committed May 29, 2013
1 parent aa9e3dd commit 6fc1d1d
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 1 deletion.
15 changes: 15 additions & 0 deletions README.md
Expand Up @@ -199,6 +199,21 @@ In a Rails app you might want to add your global listeners in an initalizer.

Global listeners are threadsafe.

## Temporary Global Listeners

You can also globally subscribe a listener for the duration of a block.

```ruby
Wisper::TemporaryListeners.with(MyListener.new) do
# do stuff
end
```

Any events broadcast within the block by any publisher will be sent to the
listeners.

To subscribe multiple listeners pass an array to `with`.

## Subscribing to selected events

By default a listener will get notified of all events it can respond to. You
Expand Down
1 change: 1 addition & 0 deletions lib/wisper.rb
Expand Up @@ -5,6 +5,7 @@
require 'wisper/registration/object'
require 'wisper/registration/block'
require 'wisper/global_listeners'
require 'wisper/temporary_listeners'

module Wisper
def self.included(base)
Expand Down
6 changes: 5 additions & 1 deletion lib/wisper/publisher.rb
Expand Up @@ -33,8 +33,12 @@ def global_registrations
GlobalListeners.registrations
end

def temporary_registrations
TemporaryListeners.registrations
end

def registrations
local_registrations.merge(global_registrations)
local_registrations + global_registrations + temporary_registrations
end

def broadcast(event, *args)
Expand Down
42 changes: 42 additions & 0 deletions lib/wisper/temporary_listeners.rb
@@ -0,0 +1,42 @@
module Wisper
class TemporaryListeners
include Singleton

def with(listener_or_listeners, options = {}, &block)
add_listeners(Array(listener_or_listeners), options)
yield
clear
end

def registrations
Thread.current[key] ||= Set.new
end

def self.with(listener_or_listeners, options = {}, &block)
instance.with(listener_or_listeners, options, &block)
end

def self.registrations
instance.registrations
end

private

def clear
registrations.clear
end

def add_listeners(listeners, options)
listeners.each { |listener| add_listener(listener, options)}
end

def add_listener(listener, options)
registrations << ObjectRegistration.new(listener, options)
end


def key
'__wisper_temporary_listeners'
end
end
end
37 changes: 37 additions & 0 deletions spec/lib/temporary_global_listeners_spec.rb
@@ -0,0 +1,37 @@
require 'spec_helper'

describe Wisper::GlobalListeners do
let(:listener_1) { double('listener') }
let(:listener_2) { double('listener') }
let(:publisher) { Object.class_eval { include Wisper::Publisher } }

describe '.with' do
it 'globally subscribes listener for duration of given block' do

listener_1.should_receive(:success)
listener_1.should_not_receive(:failure)

Wisper::TemporaryListeners.with(listener_1) do
publisher.instance_eval { broadcast(:success) }
end

publisher.instance_eval { broadcast(:failure) }
end

it 'globally subscribes listeners for duration of given block' do

listener_1.should_receive(:success)
listener_1.should_not_receive(:failure)

listener_2.should_receive(:success)
listener_2.should_not_receive(:failure)

Wisper::TemporaryListeners.with([listener_1, listener_2]) do
publisher.instance_eval { broadcast(:success) }
end

publisher.instance_eval { broadcast(:failure) }
end
end
end

0 comments on commit 6fc1d1d

Please sign in to comment.