Class: Faye::Channel::Tree

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/faye/protocol/channel.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent = nil, value = nil) ⇒ Tree

Returns a new instance of Tree.



59
60
61
62
63
# File 'lib/faye/protocol/channel.rb', line 59

def initialize(parent = nil, value = nil)
  @parent   = parent
  @value    = value
  @children = {}
end

Instance Attribute Details

#valueObject

Returns the value of attribute value.



57
58
59
# File 'lib/faye/protocol/channel.rb', line 57

def value
  @value
end

Instance Method Details

#[](name) ⇒ Object



78
79
80
81
# File 'lib/faye/protocol/channel.rb', line 78

def [](name)
  subtree = traverse(name)
  subtree ? subtree.value : nil
end

#[]=(name, value) ⇒ Object



83
84
85
86
# File 'lib/faye/protocol/channel.rb', line 83

def []=(name, value)
  subtree = traverse(name, true)
  subtree.value = value unless subtree.nil?
end

#distribute_message(message) ⇒ Object



167
168
169
170
171
# File 'lib/faye/protocol/channel.rb', line 167

def distribute_message(message)
  glob(message['channel']).each do |channel|
    channel.publish_event(:message, message['data'])
  end
end

#each(prefix = []) {|prefix, @value| ... } ⇒ Object

Yields:



69
70
71
72
# File 'lib/faye/protocol/channel.rb', line 69

def each(prefix = [], &block)
  each_child { |path, subtree| subtree.each(prefix + [path], &block) }
  yield(prefix, @value) unless @value.nil?
end

#each_childObject



65
66
67
# File 'lib/faye/protocol/channel.rb', line 65

def each_child
  @children.each { |key, subtree| yield(key, subtree) }
end

#glob(path = []) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/faye/protocol/channel.rb', line 119

def glob(path = [])
  path = Channel.parse(path) if String === path
  
  return [] if path.nil?
  return @value.nil? ? [] : [@value] if path.empty?
  
  if path == [:*]
    return @children.inject([]) do |list, (key, subtree)|
      list << subtree.value unless subtree.value.nil?
      list
    end
  end
  
  if path == [:**]
    list = map { |key, value| value }
    list.pop unless @value.nil?
    return list
  end
  
  list = @children.values_at(path.first, :*).
                   compact.
                   map { |t| t.glob(path[1..-1]) }
  
  list << @children[:**].value if @children[:**]
  list.flatten
end

#keysObject



74
75
76
# File 'lib/faye/protocol/channel.rb', line 74

def keys
  map { |key, value| '/' + key * '/' }
end

#remove(name = nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
# File 'lib/faye/protocol/channel.rb', line 88

def remove(name = nil)
  if name
    subtree = traverse(name)
    subtree.remove unless subtree.nil?
  else
    return unless @parent
    @parent.remove_child(self)
    @parent = @value = nil
  end
end

#remove_child(subtree) ⇒ Object



99
100
101
102
103
104
# File 'lib/faye/protocol/channel.rb', line 99

def remove_child(subtree)
  each_child do |key, child|
    @children.delete(key) if child == subtree
  end
  remove if @children.empty? and @value.nil?
end

#subscribe(names, callback) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/faye/protocol/channel.rb', line 146

def subscribe(names, callback)
  return unless callback
  names.each do |name|
    channel = self[name] ||= Channel.new(name)
    channel.add_subscriber(:message, callback)
  end
end

#traverse(path, create_if_absent = false) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/faye/protocol/channel.rb', line 106

def traverse(path, create_if_absent = false)
  path = Channel.parse(path) if String === path
  
  return nil if path.nil?
  return self if path.empty?
  
  subtree = @children[path.first]
  return nil if subtree.nil? and not create_if_absent
  subtree = @children[path.first] = Tree.new(self) if subtree.nil?
  
  subtree.traverse(path[1..-1], create_if_absent)
end

#unsubscribe(name, callback) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/faye/protocol/channel.rb', line 154

def unsubscribe(name, callback)
  channel = self[name]
  return false unless channel
  channel.remove_subscriber(:message, callback)
  
  if channel.unused?
    remove(name)
    true
  else
    false
  end
end