Fixed issues with Controller activation, moved activation code into Controller
This commit is contained in:
parent
3ed8af3b8b
commit
be39c5db49
6 changed files with 129 additions and 52 deletions
|
@ -26,7 +26,9 @@
|
|||
Controller::Controller() :
|
||||
m_msg_cb(),
|
||||
m_disconnect_cb(),
|
||||
m_activation_cb(),
|
||||
m_is_disconnected(false),
|
||||
m_is_active(true),
|
||||
m_udev_device()
|
||||
{
|
||||
}
|
||||
|
@ -64,6 +66,26 @@ Controller::get_udev_device() const
|
|||
return m_udev_device;
|
||||
}
|
||||
|
||||
void
|
||||
Controller::set_active(bool v)
|
||||
{
|
||||
if (m_is_active != v)
|
||||
{
|
||||
log_debug("activation status: " << v << " " << m_activation_cb);
|
||||
m_is_active = v;
|
||||
if (m_activation_cb)
|
||||
{
|
||||
m_activation_cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::set_activation_cb(const boost::function<void ()>& callback)
|
||||
{
|
||||
m_activation_cb = callback;
|
||||
}
|
||||
|
||||
bool
|
||||
Controller::is_disconnected() const
|
||||
{
|
||||
|
|
|
@ -33,7 +33,9 @@ class Controller
|
|||
protected:
|
||||
boost::function<void (const XboxGenericMsg&)> m_msg_cb;
|
||||
boost::function<void ()> m_disconnect_cb;
|
||||
boost::function<void ()> m_activation_cb;
|
||||
bool m_is_disconnected;
|
||||
bool m_is_active;
|
||||
udev_device* m_udev_device;
|
||||
|
||||
public:
|
||||
|
@ -43,9 +45,16 @@ public:
|
|||
virtual void set_rumble(uint8_t left, uint8_t right) =0;
|
||||
virtual void set_led(uint8_t status) =0;
|
||||
|
||||
virtual bool is_active() const { return true; }
|
||||
virtual void set_activation_cb(const boost::function<void ()>& callback) {}
|
||||
/** Wireless Controller start out inactive when they are not synced
|
||||
with their receiver and become active after the sync. Regular
|
||||
USB controller are always active. Active controllers can become
|
||||
inactive and vice versa. */
|
||||
virtual bool is_active() const { return m_is_active; }
|
||||
virtual void set_active(bool v);
|
||||
virtual void set_activation_cb(const boost::function<void ()>& callback);
|
||||
|
||||
/** Controllers with a disconnect status have been unplugged and are
|
||||
not coming back, thus the Controller object can be destroyed */
|
||||
virtual bool is_disconnected() const;
|
||||
virtual void set_disconnect_cb(const boost::function<void ()>& callback);
|
||||
virtual void send_disconnect();
|
||||
|
|
|
@ -30,14 +30,15 @@
|
|||
Xbox360WirelessController::Xbox360WirelessController(libusb_device* dev, int controller_id,
|
||||
bool try_detach) :
|
||||
USBController(dev),
|
||||
m_active(false),
|
||||
m_endpoint(),
|
||||
m_interface(),
|
||||
m_battery_status(),
|
||||
m_serial(),
|
||||
m_led_status(0),
|
||||
m_activation_cb()
|
||||
m_led_status(0)
|
||||
{
|
||||
// FIXME: A little bit of a hack
|
||||
m_is_active = false;
|
||||
|
||||
assert(controller_id >= 0 && controller_id < 4);
|
||||
|
||||
// FIXME: Is hardcoding those ok?
|
||||
|
@ -200,24 +201,4 @@ Xbox360WirelessController::parse(uint8_t* data, int len, XboxGenericMsg* msg_out
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Xbox360WirelessController::set_active(bool v)
|
||||
{
|
||||
if (m_active != v)
|
||||
{
|
||||
log_debug("activation status: " << v);
|
||||
m_active = v;
|
||||
if (m_activation_cb)
|
||||
{
|
||||
m_activation_cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Xbox360WirelessController::set_activation_cb(const boost::function<void ()> callback)
|
||||
{
|
||||
m_activation_cb = callback;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -30,15 +30,12 @@ struct XPadDevice;
|
|||
class Xbox360WirelessController : public USBController
|
||||
{
|
||||
private:
|
||||
bool m_active;
|
||||
int m_endpoint;
|
||||
int m_interface;
|
||||
int m_battery_status;
|
||||
std::string m_serial;
|
||||
int m_led_status;
|
||||
|
||||
boost::function<void ()> m_activation_cb;
|
||||
|
||||
public:
|
||||
Xbox360WirelessController(libusb_device* dev, int controller_id, bool try_detach);
|
||||
virtual ~Xbox360WirelessController();
|
||||
|
@ -48,12 +45,7 @@ public:
|
|||
void set_rumble(uint8_t left, uint8_t right);
|
||||
void set_led(uint8_t status);
|
||||
uint8_t get_battery_status() const;
|
||||
bool is_active() const { return m_active; }
|
||||
void set_activation_cb(const boost::function<void ()> callback);
|
||||
|
||||
private:
|
||||
void set_active(bool v);
|
||||
|
||||
private:
|
||||
Xbox360WirelessController (const Xbox360WirelessController&);
|
||||
Xbox360WirelessController& operator= (const Xbox360WirelessController&);
|
||||
|
|
|
@ -268,16 +268,6 @@ XboxdrvDaemon::create_pid_file()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
XboxdrvDaemon::on_wakeup()
|
||||
{
|
||||
log_info("got a wakeup call");
|
||||
|
||||
on_controller_disconnect();
|
||||
|
||||
return false; // remove the registered idle callback
|
||||
}
|
||||
|
||||
ControllerSlotPtr
|
||||
XboxdrvDaemon::find_free_slot(udev_device* dev)
|
||||
{
|
||||
|
@ -332,7 +322,8 @@ XboxdrvDaemon::launch_controller_thread(udev_device* udev_dev,
|
|||
{
|
||||
ControllerPtr& controller = *i;
|
||||
|
||||
controller->set_disconnect_cb(boost::bind(&XboxdrvDaemon::wakeup, this));
|
||||
controller->set_disconnect_cb(boost::bind(&g_idle_add, &XboxdrvDaemon::on_controller_disconnect_wrap, this));
|
||||
controller->set_activation_cb(boost::bind(&g_idle_add, &XboxdrvDaemon::on_controller_activate_wrap, this));
|
||||
|
||||
// FIXME: Little dirty hack
|
||||
controller->set_udev_device(udev_dev);
|
||||
|
@ -358,7 +349,6 @@ XboxdrvDaemon::launch_controller_thread(udev_device* udev_dev,
|
|||
}
|
||||
else // if (!controller->is_active())
|
||||
{
|
||||
controller->set_activation_cb(boost::bind(&XboxdrvDaemon::wakeup, this));
|
||||
m_inactive_controllers.push_back(controller);
|
||||
}
|
||||
}
|
||||
|
@ -469,10 +459,12 @@ XboxdrvDaemon::on_disconnect(ControllerSlotPtr slot)
|
|||
void
|
||||
XboxdrvDaemon::on_controller_disconnect()
|
||||
{
|
||||
log_tmp("on_controller_disconnect");
|
||||
|
||||
// cleanup active controllers in slots
|
||||
for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
|
||||
{
|
||||
if ((*i)->get_controller()->is_disconnected())
|
||||
if ((*i)->get_controller() && (*i)->get_controller()->is_disconnected())
|
||||
{
|
||||
disconnect(*i); // discard the ControllerPtr
|
||||
}
|
||||
|
@ -485,9 +477,12 @@ XboxdrvDaemon::on_controller_disconnect()
|
|||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::wakeup()
|
||||
XboxdrvDaemon::on_controller_activate()
|
||||
{
|
||||
g_idle_add(&XboxdrvDaemon::on_wakeup_wrap, this);
|
||||
log_tmp("on_controller_activate");
|
||||
|
||||
cleanup_threads();
|
||||
check_thread_status();
|
||||
}
|
||||
|
||||
std::string
|
||||
|
@ -541,4 +536,75 @@ XboxdrvDaemon::on_sigint(int)
|
|||
XboxdrvDaemon::current()->shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::cleanup_threads()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
|
||||
{
|
||||
if ((*i)->is_connected())
|
||||
{
|
||||
count += 1;
|
||||
on_disconnect(*i);
|
||||
|
||||
// disconnect slot and put the controller back into the inactive group
|
||||
m_inactive_controllers.push_back((*i)->disconnect());
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
log_info("cleaned up " << count << " thread(s), free slots: " <<
|
||||
get_free_slot_count() << "/" << m_controller_slots.size());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::check_thread_status()
|
||||
{
|
||||
// check for inactive controller and free the slots
|
||||
for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
|
||||
{
|
||||
// if a slot contains an inactive controller, disconnect it and save
|
||||
// the controller for later when it might be active again
|
||||
if ((*i)->get_controller() && !(*i)->get_controller()->is_active())
|
||||
{
|
||||
ControllerPtr controller = disconnect(*i);
|
||||
m_inactive_controllers.push_back(controller);
|
||||
}
|
||||
}
|
||||
|
||||
// check for activated controller and connect them to a slot
|
||||
for(Controllers::iterator i = m_inactive_controllers.begin(); i != m_inactive_controllers.end(); ++i)
|
||||
{
|
||||
if (!*i)
|
||||
{
|
||||
log_error("NULL in m_inactive_controllers, shouldn't happen");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*i)->is_active())
|
||||
{
|
||||
ControllerSlotPtr slot = find_free_slot((*i)->get_udev_device());
|
||||
if (!slot)
|
||||
{
|
||||
log_info("couldn't find a free slot for activated controller");
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(slot, *i);
|
||||
|
||||
// successfully connected the controller, so set it to NULL and cleanup later
|
||||
*i = ControllerPtr();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup inactive controller
|
||||
m_inactive_controllers.erase(std::remove(m_inactive_controllers.begin(), m_inactive_controllers.end(), ControllerPtr()),
|
||||
m_inactive_controllers.end());
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -82,13 +82,20 @@ private:
|
|||
void on_disconnect(ControllerSlotPtr slot);
|
||||
|
||||
void on_controller_disconnect();
|
||||
void on_controller_activate();
|
||||
|
||||
void wakeup();
|
||||
void check_thread_status();
|
||||
void cleanup_threads();
|
||||
|
||||
private:
|
||||
bool on_wakeup();
|
||||
static gboolean on_wakeup_wrap(gpointer data) {
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_wakeup();
|
||||
static gboolean on_controller_disconnect_wrap(gpointer data) {
|
||||
static_cast<XboxdrvDaemon*>(data)->on_controller_disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
static gboolean on_controller_activate_wrap(gpointer data) {
|
||||
static_cast<XboxdrvDaemon*>(data)->on_controller_activate();
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue