commit 06f77931318bb489eca93b67514ccc34db6f788e
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Tue Nov 16 00:15:43 2010 +0100

    [evol] reworked notification system a bit (global registration)

diff --git a/lib/cyborghood/cyborg.rb b/lib/cyborghood/cyborg.rb
index b3493c8..2fa982c 100644
--- a/lib/cyborghood/cyborg.rb
+++ b/lib/cyborghood/cyborg.rb
@@ -25,7 +25,7 @@ module CyborgHood
     include I18nTranslation
     bindtextdomain("cyborghood", {:path => Config::L10N_DIR, :charset => "UTF-8"})
 
-    attr_reader :name, :system_notification, :user_notification
+    attr_reader :name
 
     def initialize
       @name = self.class.name.split("::").last
@@ -45,15 +45,27 @@ module CyborgHood
         end
       end
 
+      @channels = {}
+
       setup
 
       logger.info "Bot '#{self.human_name}' loaded"
     end
 
-    def setup
-      @system_notification = EventMachine::Channel.new
-      @user_notification = EventMachine::Channel.new
+    # #^.*/system$# categories are reserved
+    # but you may enhance or break the system as you wish
+    def get_channel(name)
+      return @channels[name] if @channels.has_key? name
+      @channels[name] = EventMachine::Channel.new
+    end
 
+    def drop_channel(name)
+      @channels.delete(name)
+    end
+
+    def setup
+      @system_notification_name = 'global/system'
+      @system_notification = get_channel(@system_notification_name)
       @system_notification_processing = @system_notification.subscribe do |msg|
         process_system_notification(msg)
       end
@@ -88,6 +100,10 @@ module CyborgHood
 
     def try_stop
       if ready_to_stop?
+        @system_notification.unsubscribe(@system_notification_processing)
+        @system_notification_processing = nil
+        drop_channel(@system_notification_name)
+
         EventMachine.stop_event_loop
       else
         EventMachine.next_tick { try_stop }
diff --git a/lib/cyborghood/cyborg/conversation.rb b/lib/cyborghood/cyborg/conversation.rb
index cd55366..4a65732 100644
--- a/lib/cyborghood/cyborg/conversation.rb
+++ b/lib/cyborghood/cyborg/conversation.rb
@@ -111,7 +111,6 @@ module CyborgHood
     MAXIMUM_LINES = 1024
 
     attr_reader :bot, :peer_name, :peer_capabilities, :protocol
-    attr_reader :system_notification, :user_notification
 
     def initialize(bot, block = nil)
       @bot = bot
@@ -138,12 +137,12 @@ module CyborgHood
       @peer_name = nil
       @peer_capabilities = []
 
-      @system_notification = EventMachine::Channel.new
-      @user_notification = EventMachine::Channel.new
-
       @protocol = BotProtocol.new(self)
 
       @pending_thread_close = Set.new
+      # we don't know the peer name yet
+      @system_notification_name = "peer/#{identifier}/system"
+      @system_notification = @bot.get_channel(@system_notification_name)
       @system_notification_processing = @system_notification.subscribe do |msg|
         process_system_notification(msg)
       end
@@ -215,6 +214,7 @@ module CyborgHood
     def unbind
       logger.info "Conversation finished with #{identifier} (#{@peer_name})"
       @bot.unregister_communication @peer_name unless @peer_name.nil?
+      @bot.drop_channel(@system_notification_name)
       @conv_threads.each_value {|s| s.close(false) }
       @conv_threads = {}
       @conv_threads_index = {}
@@ -277,7 +277,10 @@ module CyborgHood
 
       # if only the system thread remains, notify idleness
       if @conv_threads.size == 1
-        @bot.system_notification << { :topic => 'CONVERSATION IDLE', :peer => peer_name }
+        @bot.get_channel('global/system') << {
+          :topic => 'CONVERSATION IDLE',
+          :peer => peer_name
+        }
       end
     end
 
@@ -300,6 +303,10 @@ module CyborgHood
       end
     end
 
+    def identifier
+      "#{@bot.identifier_prefix}/#{@signature}"
+    end
+
     protected
 
     def clear_receive_info
@@ -382,10 +389,6 @@ module CyborgHood
       @split_data = []
     end
 
-    def identifier
-      "#{@bot.identifier_prefix}/#{@signature}"
-    end
-
     def process_system_notification(msg)
       return unless msg[:topic] == 'THREAD IDLE'
 
diff --git a/lib/cyborghood/cyborg/protocol.rb b/lib/cyborghood/cyborg/protocol.rb
index a571e3e..0155db9 100644
--- a/lib/cyborghood/cyborg/protocol.rb
+++ b/lib/cyborghood/cyborg/protocol.rb
@@ -174,7 +174,7 @@ module CyborgHood
     end
 
     def receive_notify_event(message)
-      @conversation.user_notification << {
+      @conversation.bot.get_channel("peer/#{@conversation.peer_name}/incoming") << {
         :from   => message.conversation.peer_id,
         :topic  => message.action_parameters[:name],
         :info   => message.action_parameters[:info]
@@ -312,8 +312,10 @@ module CyborgHood
 
     def check_thread_idle(conv_thread)
       return if @action_followup.has_key? conv_thread.id
-
-      @conversation.system_notification << { :topic => 'THREAD IDLE', :thread => conv_thread.name }
+      @conversation.bot.get_channel("peer/#{@conversation.identifier}/system") << {
+        :topic => 'THREAD IDLE',
+        :thread => conv_thread.name
+      }
     end
   end
 end
