Moved ControllerSlot to a separate file
This commit is contained in:
parent
3f0350ee34
commit
8e8f69f749
4 changed files with 180 additions and 82 deletions
59
src/controller_slot.cpp
Normal file
59
src/controller_slot.cpp
Normal 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
92
src/controller_slot.hpp
Normal 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 */
|
|
@ -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);
|
||||
|
|
|
@ -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&);
|
||||
|
|
Loading…
Add table
Reference in a new issue