commit bc642412b31c7f4a3066a649cd06cc2a0acc4b8b
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Sat Nov 6 21:51:14 2010 +0100

    [evol] moved EM loop in Cyborg, simplified and enhanced bot interface, and made Conversation common for any connection type

diff --git a/bin/mapmaker b/bin/mapmaker
index 6226dab..f023c31 100755
--- a/bin/mapmaker
+++ b/bin/mapmaker
@@ -46,7 +46,7 @@ module CyborgHood
     bindtextdomain("cyborghood_mapmaker", {:path => Config::L10N_DIR, :charset => "UTF-8"})
 
     class MapMaker < Cyborg
-      include SimpleServer
+      include BotServer
 
       def interface
         MapMakerInterface.instance
diff --git a/lib/cyborghood/cyborg.rb b/lib/cyborghood/cyborg.rb
index b7d4ebc..057f9ce 100644
--- a/lib/cyborghood/cyborg.rb
+++ b/lib/cyborghood/cyborg.rb
@@ -17,6 +17,7 @@
 #++
 
 require 'cyborghood'
+require 'eventmachine'
 
 
 module CyborgHood
@@ -53,10 +54,27 @@ module CyborgHood
 
     def run
       logger.info "Bot starting"
+      EventMachine.run do
+        start_work
+      end
+    end
+
+    def start_work
+      # use "aspects" Modules to define behaviors
     end
 
     def ask_to_stop
       logger.info "Bot was asked to stop..."
+      EventMachine.stop
+    end
+
+    # core capabilities
+    def capabilities
+      []
+    end
+
+    def schedule_task(callback, &task)
+      EventMachine.defer(task, callback)
     end
   end
 end
diff --git a/lib/cyborghood/cyborg/conversation.rb b/lib/cyborghood/cyborg/conversation.rb
index 6a03756..9f701d8 100644
--- a/lib/cyborghood/cyborg/conversation.rb
+++ b/lib/cyborghood/cyborg/conversation.rb
@@ -117,10 +117,6 @@ module CyborgHood
       @protocol = BotProtocol.new(self)
     end
 
-    def capabilities
-      []
-    end
-
     def post_init
       logger.debug "New conversation with #{identifier}"
     end
@@ -306,17 +302,9 @@ module CyborgHood
       @split_data_message = nil
       @split_data = []
     end
-  end
-
-  class ConversationUNIXSocket < Conversation
-    public_class_method :new
 
     def identifier
-      "unix_socket/#{@signature}"
-    end
-
-    def capabilities
-      super + []
+      "#{@bot.identifier_prefix}/#{@signature}"
     end
   end
 end
diff --git a/lib/cyborghood/cyborg/protocol.rb b/lib/cyborghood/cyborg/protocol.rb
index 3ed7155..1573acd 100644
--- a/lib/cyborghood/cyborg/protocol.rb
+++ b/lib/cyborghood/cyborg/protocol.rb
@@ -89,7 +89,7 @@ module CyborgHood
     end
 
     def receive_request_capabilities(message)
-      send_reply_result(message, @conversation.capabilities + CAPABILITIES)
+      send_reply_result(message, @conversation.bot.capabilities + CAPABILITIES)
     end
 
     def receive_request_call(message)
diff --git a/lib/cyborghood/cyborg/server.rb b/lib/cyborghood/cyborg/server.rb
index 8749f1e..9a31345 100644
--- a/lib/cyborghood/cyborg/server.rb
+++ b/lib/cyborghood/cyborg/server.rb
@@ -16,80 +16,36 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #++
 
-require 'eventmachine'
 require 'cyborghood/cyborg/interface'
 require 'cyborghood/cyborg/conversation'
 
 
 module CyborgHood
-  class BotServer
-    private_class_method :new
-
-    attr_reader :interface
-
-    def self.build(interface)
-      case Config.instance.botnet.connection_type
-      when 'unix_socket'
-        return BotServerUNIXSocket.new(interface)
-      else
-        raise CyberError.new(:unrecoverable, "config", "Unknown botnet connection type")
-      end
-    end
-
-    def initialize(interface)
-      @interface = interface
-
-      @config = Config.instance
-
-      @comm_list = {}
-    end
-
-    def run
-      EventMachine.run do
-        yield
-      end
-    end
-
-    def stop
-      @comm_list.values.each {|conv| conv.bye }
-      EventMachine.stop
-    end
-
-    # used to quit properly and later to reuse communication channels
-    def register_communication(peer, conversation)
-      @comm_list[peer] = conversation
-    end
-
-    def unregister_communication(peer)
-      @comm_list.delete(peer)
-    end
-
-    def schedule_task(callback, &task)
-      EventMachine.defer(task, callback)
-    end
-  end
-
-  class BotServerUNIXSocket < BotServer
-    public_class_method :new
-
-    def initialize(interface)
-      super(interface)
-
+  module BotServerUNIXSocket
+    def setup
+      super
       @socket = File.join(Config::RUN_DIR, @config.bot_name.downcase + ".sock")
       at_exit { remove_socket_file }
     end
 
-    def run
-      super do
-        EventMachine.start_unix_domain_server(@socket, ConversationUNIXSocket, self)
-      end
+    def start_work
+      super
+      EventMachine.start_unix_domain_server(@socket, Conversation, self)
     end
 
-    private
-
     def remove_socket_file
       File.delete(@socket) if @socket && File.exist?(@socket)
     end
+
+    # backend-specific capabilities
+    def capabilities
+      super + []
+    end
+
+    # TODO: should be common to the future BotClientUNIXSocket
+    def identifier_prefix
+      "unix_socket"
+    end
   end
 
   # default interface if not overridden
@@ -98,19 +54,34 @@ module CyborgHood
     include CyborgServerRootInterfaceAddon
   end
 
-  module SimpleServer
+  module BotServer
+    attr_reader :interface
+
+    def self.included(base)
+      case Config.instance.botnet.connection_type
+      when 'unix_socket'
+        return base.class_eval("include BotServerUNIXSocket")
+      else
+        raise CyberError.new(:unrecoverable, "config", "Unknown botnet connection type")
+      end
+    end
+
     def setup
       super
-      @server = BotServer.build(self.interface)
+      @comm_list = {}
     end
 
-    def run
-      super
-      @server.run
+    # used to quit properly and later to reuse communication channels
+    def register_communication(peer, conversation)
+      @comm_list[peer] = conversation
+    end
+
+    def unregister_communication(peer)
+      @comm_list.delete(peer)
     end
 
     def ask_to_stop
-      @server.stop
+      @comm_list.values.each {|conv| conv.bye }
       super
     end
 
