From 8e8f69f74917c9ef467800579d2a956a88c164c4 Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Sun, 30 Jan 2011 16:31:50 +0100
Subject: [PATCH] Moved ControllerSlot to a separate file

---
 src/controller_slot.cpp | 59 ++++++++++++++++++++++++++
 src/controller_slot.hpp | 92 +++++++++++++++++++++++++++++++++++++++++
 src/xboxdrv_daemon.cpp  | 53 +++++++++++-------------
 src/xboxdrv_daemon.hpp  | 58 +++-----------------------
 4 files changed, 180 insertions(+), 82 deletions(-)
 create mode 100644 src/controller_slot.cpp
 create mode 100644 src/controller_slot.hpp

diff --git a/src/controller_slot.cpp b/src/controller_slot.cpp
new file mode 100644
index 0000000..4491ad4
--- /dev/null
+++ b/src/controller_slot.cpp
@@ -0,0 +1,59 @@
+/*
+**  Xbox360 USB Gamepad Userspace Driver
+**  Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
+**
+**  This program is free software: you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation, either version 3 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "controller_slot.hpp"
+
+#include "xboxdrv_thread.hpp"
+
+void
+ControllerSlot::connect(XboxdrvThread* thread)
+{
+  assert(thread == 0);
+  m_thread = thread;
+}
+
+void
+ControllerSlot::disconnect()
+{
+  delete m_thread;
+  m_thread = 0;
+}
+
+bool
+ControllerSlot::try_disconnect()
+{
+  assert(m_thread);
+
+  if (m_thread->try_join_thread())
+  {
+    disconnect();
+    return true;
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool
+ControllerSlot::is_connected() const
+{
+  return m_thread;
+}
+
+/* EOF */
diff --git a/src/controller_slot.hpp b/src/controller_slot.hpp
new file mode 100644
index 0000000..9c0957f
--- /dev/null
+++ b/src/controller_slot.hpp
@@ -0,0 +1,92 @@
+/*
+**  Xbox360 USB Gamepad Userspace Driver
+**  Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
+**
+**  This program is free software: you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation, either version 3 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef HEADER_XBOXDRV_CONTROLLER_SLOT_HPP
+#define HEADER_XBOXDRV_CONTROLLER_SLOT_HPP
+
+#include <vector>
+
+#include "controller_slot_config.hpp"
+
+class XboxdrvThread;
+
+class ControllerSlot
+{
+private:
+  int m_id;
+  ControllerSlotConfigPtr m_config;
+  std::vector<ControllerMatchRulePtr> m_rules;
+  int m_led_status;
+  XboxdrvThread* m_thread;
+    
+public:
+  ControllerSlot() :
+    m_id(),
+    m_config(),
+    m_rules(),
+    m_led_status(-1),
+    m_thread(0)
+  {}
+
+  ControllerSlot(int id_,
+                 ControllerSlotConfigPtr config_,
+                 std::vector<ControllerMatchRulePtr> rules_,
+                 int led_status_,
+                 XboxdrvThread* thread_ = 0) :
+    m_id(id_),
+    m_config(config_),
+    m_rules(rules_),
+    m_led_status(led_status_),
+    m_thread(thread_)
+  {}
+
+  ControllerSlot(const ControllerSlot& rhs) :
+    m_id(rhs.m_id),
+    m_config(rhs.m_config),
+    m_rules(rhs.m_rules),
+    m_led_status(rhs.m_led_status),
+    m_thread(rhs.m_thread)
+  {}
+
+  ControllerSlot& operator=(const ControllerSlot& rhs)
+  {
+    if (&rhs != this)
+    {
+      m_id     = rhs.m_id;
+      m_config = rhs.m_config;
+      m_rules  = rhs.m_rules;
+      m_led_status = rhs.m_led_status;
+      m_thread = rhs.m_thread;
+    }
+    return *this;
+  }
+
+  bool is_connected() const;
+  void connect(XboxdrvThread* thread);
+  void disconnect();
+  bool try_disconnect();
+
+  const std::vector<ControllerMatchRulePtr>& get_rules() const { return m_rules; }
+  int get_led_status() const { return m_led_status; }
+  int get_id() const { return m_id; }
+  ControllerSlotConfigPtr get_config() const { return m_config; }
+};
+
+#endif
+
+/* EOF */
diff --git a/src/xboxdrv_daemon.cpp b/src/xboxdrv_daemon.cpp
index c835eb1..ec587e8 100644
--- a/src/xboxdrv_daemon.cpp
+++ b/src/xboxdrv_daemon.cpp
@@ -101,8 +101,7 @@ XboxdrvDaemon::~XboxdrvDaemon()
 {
   for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
   {
-    delete i->thread;
-    i->thread = 0;
+    i->disconnect();
   }
 
   udev_monitor_unref(m_monitor);
@@ -116,15 +115,12 @@ XboxdrvDaemon::cleanup_threads()
 
   for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
   {
-    if (i->thread)
+    if (i->is_connected())
     {
-      if (i->thread->try_join_thread())
+      if (i->try_disconnect())
       {
-        delete i->thread;
-        i->thread = 0;
         count += 1;
-
-        on_disconnect();
+        on_disconnect(*i);
       }
     }
   }
@@ -433,33 +429,32 @@ XboxdrvDaemon::print_info(struct udev_device* device)
   log_debug("\\----------------------------------------------");
 }
 
-XboxdrvDaemon::ControllerSlot*
-XboxdrvDaemon::find_free_slot(udev_device* dev) const
+ControllerSlot*
+XboxdrvDaemon::find_free_slot(udev_device* dev)
 {
   // first pass, look for slots where the rules match the given vendor:product, bus:dev
-  for(ControllerSlots::const_iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
+  for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
   {
-    if (i->thread == 0)
+    if (!i->is_connected())
     {
       // found a free slot, check if the rules match
-      for(std::vector<ControllerMatchRulePtr>::const_iterator rule = i->rules.begin(); rule != i->rules.end(); ++rule)
+      for(std::vector<ControllerMatchRulePtr>::const_iterator rule = i->get_rules().begin(); 
+          rule != i->get_rules().end(); ++rule)
       {
         if ((*rule)->match(dev))
         {
-          // FIXME: ugly const_cast
-          return const_cast<ControllerSlot*>(&(*i));
+          return &(*i);
         }
       }
     }
   }
 
   // second path, look for slots that don't have any rules and thus match everything
-  for(ControllerSlots::const_iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
+  for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
   {
-    if (i->thread == 0 && i->rules.empty())
+    if (!i->is_connected() && i->get_rules().empty())
     {
-      // FIXME: ugly const_cast
-      return const_cast<ControllerSlot*>(&(*i));
+      return &(*i);
     }
   }
     
@@ -483,19 +478,19 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
   {
     std::auto_ptr<XboxGenericController> controller = XboxControllerFactory::create(dev_type, dev, opts);
 
-    if (slot.led_status == -1)
+    if (slot.get_led_status() == -1)
     {
-      controller->set_led(2 + (slot.id % 4));
+      controller->set_led(2 + (slot.get_id() % 4));
     }
     else
     {
-      controller->set_led(slot.led_status);
+      controller->set_led(slot.get_led_status());
     }
 
     std::auto_ptr<MessageProcessor> message_proc;
     if (m_uinput.get())
     {
-      message_proc.reset(new UInputMessageProcessor(*m_uinput, slot.config, opts));
+      message_proc.reset(new UInputMessageProcessor(*m_uinput, slot.get_config(), opts));
     }
     else
     {
@@ -504,14 +499,14 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
 
     std::auto_ptr<XboxdrvThread> thread(new XboxdrvThread(message_proc, controller, opts));
     thread->start_thread(opts);
-    slot.thread = thread.release();
+    slot.connect(thread.release());
 
-    on_connect();
+    on_connect(slot);
 
     log_info("launched XboxdrvThread for " << boost::format("%03d:%03d")
       % static_cast<int>(busnum) 
       % static_cast<int>(devnum)
-             << " in slot " << slot.id << ", free slots: " 
+             << " in slot " << slot.get_id() << ", free slots: " 
              << get_free_slot_count() << "/" << m_controller_slots.size());
   }
 }
@@ -523,7 +518,7 @@ XboxdrvDaemon::get_free_slot_count() const
 
   for(ControllerSlots::const_iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
   {
-    if (i->thread == 0)
+    if (!i->is_connected())
     {
       slot_count += 1;
     }
@@ -533,14 +528,14 @@ XboxdrvDaemon::get_free_slot_count() const
 }
 
 void
-XboxdrvDaemon::on_connect()
+XboxdrvDaemon::on_connect(const ControllerSlot& slot)
 {
   log_info("launching connect script");
   spawn_exe(m_opts.on_connect);
 }
 
 void
-XboxdrvDaemon::on_disconnect()
+XboxdrvDaemon::on_disconnect(const ControllerSlot& slot)
 {
   log_info("launching disconnect script");
   spawn_exe(m_opts.on_disconnect);
diff --git a/src/xboxdrv_daemon.hpp b/src/xboxdrv_daemon.hpp
index 3931e2f..c15f5dd 100644
--- a/src/xboxdrv_daemon.hpp
+++ b/src/xboxdrv_daemon.hpp
@@ -22,6 +22,7 @@
 #include <libudev.h>
 
 #include "controller_slot_config.hpp"
+#include "controller_slot.hpp"
 
 class Options;
 class UInput;
@@ -35,56 +36,7 @@ private:
   struct udev* m_udev;
   struct udev_monitor* m_monitor;
 
-  struct ControllerSlot
-  {
-    int id;
-    ControllerSlotConfigPtr config;
-    std::vector<ControllerMatchRulePtr> rules;
-    int led_status;
-    XboxdrvThread* thread;
-    
-    ControllerSlot() :
-      id(),
-      config(),
-      rules(),
-      led_status(-1),
-      thread(0)
-    {}
-
-    ControllerSlot(int id_,
-                   ControllerSlotConfigPtr config_,
-                   std::vector<ControllerMatchRulePtr> rules_,
-                   int led_status_,
-                   XboxdrvThread* thread_ = 0) :
-      id(id_),
-      config(config_),
-      rules(rules_),
-      led_status(led_status_),
-      thread(thread_)
-    {}
-
-    ControllerSlot(const ControllerSlot& rhs) :
-      id(rhs.id),
-      config(rhs.config),
-      rules(rhs.rules),
-      led_status(rhs.led_status),
-      thread(rhs.thread)
-    {}
-
-    ControllerSlot& operator=(const ControllerSlot& rhs)
-    {
-      if (&rhs != this)
-      {
-        id     = rhs.id;
-        config = rhs.config;
-        rules  = rhs.rules;
-        led_status = rhs.led_status;
-        thread = rhs.thread;
-      }
-      return *this;
-    }
-  };
-  
+ 
   typedef std::vector<ControllerSlot> ControllerSlots;
   ControllerSlots m_controller_slots;
 
@@ -104,7 +56,7 @@ private:
 
   void run_loop(const Options& opts);
 
-  ControllerSlot* find_free_slot(udev_device* dev) const;
+  ControllerSlot* find_free_slot(udev_device* dev);
 
   void cleanup_threads();
   void process_match(const Options& opts, struct udev_device* device);
@@ -114,8 +66,8 @@ private:
                       ControllerSlot& slot);
   int get_free_slot_count() const;
   
-  void on_connect();
-  void on_disconnect();
+  void on_connect(const ControllerSlot& slot);
+  void on_disconnect(const ControllerSlot& slot);
 
 private:
   XboxdrvDaemon(const XboxdrvDaemon&);