Class: Nanoc::Core::NotificationCenter

Inherits:
Object
  • Object
show all
Defined in:
lib/nanoc/core/notification_center.rb

Overview

Provides a way to send notifications between objects. It allows blocks associated with a certain notification name to be registered; these blocks will be called when the notification with the given name is posted.

It is a slightly different implementation of the Observer pattern; the table of subscribers is not stored in the observable object itself, but in the notification center.

Constant Summary collapse

DONE =
Object.new
SYNC =
Object.new

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeNotificationCenter

Returns a new instance of NotificationCenter.



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/nanoc/core/notification_center.rb', line 16

def initialize
  @thread = nil

  # name => observers dictionary
  @notifications = Hash.new { |hash, name| hash[name] = [] }

  @queue = Queue.new

  @sync_queue = Queue.new
  on(SYNC, self) { @sync_queue << true }
end

Class Method Details

.force_resetObject



95
96
97
98
# File 'lib/nanoc/core/notification_center.rb', line 95

def force_reset
  instance.force_stop
  @_instance = nil
end

.instanceObject



74
75
76
# File 'lib/nanoc/core/notification_center.rb', line 74

def instance
  @_instance ||= new.tap(&:start)
end

.on(name, id = nil) ⇒ Object



78
79
80
# File 'lib/nanoc/core/notification_center.rb', line 78

def on(name, id = nil, &)
  instance.on(name, id, &)
end

.post(name, *args) ⇒ Object



82
83
84
# File 'lib/nanoc/core/notification_center.rb', line 82

def post(name, *args)
  instance.post(name, *args)
end

.remove(name, id) ⇒ Object



86
87
88
# File 'lib/nanoc/core/notification_center.rb', line 86

def remove(name, id)
  instance.remove(name, id)
end

.resetObject



90
91
92
93
# File 'lib/nanoc/core/notification_center.rb', line 90

def reset
  instance.stop
  @_instance = nil
end

.syncObject



100
101
102
# File 'lib/nanoc/core/notification_center.rb', line 100

def sync
  instance.sync
end

Instance Method Details

#force_stopObject



51
52
53
# File 'lib/nanoc/core/notification_center.rb', line 51

def force_stop
  @queue << DONE
end

#on(name, id = nil, &block) ⇒ Object



55
56
57
# File 'lib/nanoc/core/notification_center.rb', line 55

def on(name, id = nil, &block)
  @notifications[name] << { id:, block: }
end

#post(name, *args) ⇒ Object



63
64
65
66
# File 'lib/nanoc/core/notification_center.rb', line 63

def post(name, *args)
  @queue << [name, args]
  self
end

#remove(name, id) ⇒ Object



59
60
61
# File 'lib/nanoc/core/notification_center.rb', line 59

def remove(name, id)
  @notifications[name].reject! { |i| i[:id] == id }
end

#startObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/nanoc/core/notification_center.rb', line 28

def start
  @thread ||= Thread.new do # rubocop:disable Naming/MemoizedInstanceVariableName
    Thread.current.abort_on_exception = true

    loop do
      elem = @queue.pop
      break if DONE.equal?(elem)

      name = elem[0]
      args = elem[1]

      @notifications[name].each do |observer|
        observer[:block].call(*args)
      end
    end
  end
end

#stopObject



46
47
48
49
# File 'lib/nanoc/core/notification_center.rb', line 46

def stop
  @queue << DONE
  @thread.join
end

#syncObject



68
69
70
71
# File 'lib/nanoc/core/notification_center.rb', line 68

def sync
  post(SYNC)
  @sync_queue.pop
end