Moved ControllerSlot to a separate file

This commit is contained in:
Ingo Ruhnke 2011-01-30 16:31:50 +01:00
parent 3f0350ee34
commit 8e8f69f749
4 changed files with 180 additions and 82 deletions

59
src/controller_slot.cpp Normal file
View file

@ -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 */

92
src/controller_slot.hpp Normal file
View file

@ -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 */

View file

@ -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);

View file

@ -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&);