much better input-device class registration

This commit is contained in:
Jack Andersen
2015-04-29 21:01:55 -10:00
parent d4b1211c24
commit 4b8651b844
19 changed files with 184 additions and 106 deletions

View File

@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
namespace boo
{
@@ -23,16 +24,18 @@ public:
virtual ~CDeviceBase();
void closeDevice();
virtual void deviceDisconnected()=0;
virtual void deviceError(const char* error) {fprintf(stderr, "%s\n", error);}
/* Low-Level API */
bool sendInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length);
size_t receiveInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length);
virtual void transferCycle() {};
virtual void finalCycle() {};
virtual void initialCycle() {}
virtual void transferCycle() {}
virtual void finalCycle() {}
/* High-Level API */
bool sendReport(const uint8_t* data, size_t length);
virtual size_t receiveReport(uint8_t* data, size_t length) {};
virtual size_t receiveReport(uint8_t* data, size_t length) {return 0;}
};

View File

@@ -6,7 +6,8 @@
#include <stdexcept>
#include "CDeviceToken.hpp"
#include "IHIDListener.hpp"
#include "DeviceClasses.hpp"
#include "SDeviceSignature.hpp"
#include <string.h>
namespace boo
{
@@ -24,7 +25,7 @@ public:
private:
/* Types this finder is interested in (immutable) */
EDeviceMask m_types;
SDeviceSignature::TDeviceSignatureSet m_types;
/* Platform-specific USB event registration
* (for auto-scanning, NULL if not registered) */
@@ -45,9 +46,10 @@ private:
}
inline void _insertToken(CDeviceToken&& token)
{
if (BooDeviceMatchToken(token, m_types)) {
if (SDeviceSignature::DeviceMatchToken(token, m_types)) {
m_tokensLock.lock();
TInsertedDeviceToken inseredTok = m_tokens.insert(std::make_pair(token.getDevicePath(), std::move(token)));
TInsertedDeviceToken inseredTok =
m_tokens.insert(std::make_pair(token.getDevicePath(), std::move(token)));
m_tokensLock.unlock();
deviceConnected(inseredTok.first->second);
}
@@ -81,12 +83,22 @@ public:
};
/* Application must specify its interested device-types */
CDeviceFinder(EDeviceMask types)
: m_types(types), m_listener(NULL)
CDeviceFinder(std::vector<const char*> types)
: m_listener(NULL)
{
if (skDevFinder)
throw std::runtime_error("only one instance of CDeviceFinder may be constructed");
skDevFinder = this;
for (const char* typeName : types)
{
const SDeviceSignature* sigIter = BOO_DEVICE_SIGS;
while (sigIter->m_name)
{
if (!strcmp(sigIter->m_name, typeName))
m_types.push_back(sigIter);
++sigIter;
}
}
}
~CDeviceFinder()
{
@@ -97,7 +109,7 @@ public:
}
/* Get interested device-type mask */
inline EDeviceMask getTypes() const {return m_types;}
inline const SDeviceSignature::TDeviceSignatureSet& getTypes() const {return m_types;}
/* Iterable set of tokens */
inline CDeviceTokensHandle getTokens() {return CDeviceTokensHandle(*this);}

View File

@@ -3,7 +3,7 @@
#include <string>
#include "CDeviceBase.hpp"
#include "DeviceClasses.hpp"
#include "SDeviceSignature.hpp"
namespace boo
{
@@ -48,7 +48,7 @@ public:
inline CDeviceBase* openAndGetDevice()
{
if (!m_connectedDev)
m_connectedDev = BooDeviceNew(*this);
m_connectedDev = SDeviceSignature::DeviceNew(*this);
return m_connectedDev;
}

View File

@@ -54,6 +54,7 @@ class CDolphinSmashAdapter final : public CDeviceBase
uint8_t m_rumbleState;
bool m_didHandshake;
void deviceDisconnected();
void initialCycle();
void transferCycle();
void finalCycle();
public:

View File

@@ -1,32 +0,0 @@
#ifndef CDEVICECLASSES_HPP
#define CDEVICECLASSES_HPP
#include "CDolphinSmashAdapter.hpp"
#include "CRevolutionPad.hpp"
#include "CCafeProPad.hpp"
#include "CDualshockPad.hpp"
#include "CGenericPad.hpp"
namespace boo
{
#define VID_NINTENDO 0x57e
#define PID_SMASH_ADAPTER 0x337
enum EDeviceMask
{
DEV_NONE = 0,
DEV_DOL_SMASH_ADAPTER = 1<<0,
DEV_RVL_PAD = 1<<1,
DEV_CAFE_PRO_PAD = 1<<2,
DEV_DUALSHOCK_PAD = 1<<3,
DEV_GENERIC_PAD = 1<<4,
DEV_ALL = 0xff
};
bool BooDeviceMatchToken(const CDeviceToken& token, EDeviceMask mask);
CDeviceBase* BooDeviceNew(CDeviceToken& token);
}
#endif // CDEVICECLASSES_HPP

View File

@@ -15,7 +15,7 @@ class CDeviceFinder;
class IHIDListener
{
public:
virtual ~IHIDListener() {};
virtual ~IHIDListener() {}
/* Automatic device scanning */
virtual bool startScanning()=0;

View File

@@ -0,0 +1,37 @@
#ifndef SDeviceSignature_HPP
#define SDeviceSignature_HPP
#include <vector>
#include <functional>
namespace boo
{
class CDeviceToken;
class CDeviceBase;
struct SDeviceSignature
{
typedef std::vector<const SDeviceSignature*> TDeviceSignatureSet;
typedef std::function<CDeviceBase*(CDeviceToken*)> TFactoryLambda;
const char* m_name;
unsigned m_vid, m_pid;
bool m_lowLevel;
TFactoryLambda m_factory;
SDeviceSignature() : m_name(NULL) {} /* Sentinel constructor */
SDeviceSignature(const char* name, unsigned vid, unsigned pid, bool lowLevel, TFactoryLambda&& factory)
: m_name(name), m_vid(vid), m_pid(pid), m_lowLevel(lowLevel), m_factory(factory) {}
static bool DeviceMatchToken(const CDeviceToken& token, const TDeviceSignatureSet& sigSet);
static CDeviceBase* DeviceNew(CDeviceToken& token);
};
#define DEVICE_SIG(name, vid, pid, lowLevel) \
SDeviceSignature(#name, vid, pid, lowLevel, [](CDeviceToken* tok) -> CDeviceBase* {return new name(tok);})
#define DEVICE_SIG_SENTINEL() SDeviceSignature()
extern const SDeviceSignature BOO_DEVICE_SIGS[];
}
#endif // SDeviceSignature_HPP