mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-16 16:37:20 +00:00
IOKit input refactor
This commit is contained in:
@@ -4,39 +4,50 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../System.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
class DeviceToken;
|
||||
class IHIDDevice;
|
||||
|
||||
class DeviceBase
|
||||
enum class HIDReportType
|
||||
{
|
||||
Input,
|
||||
Output,
|
||||
Feature
|
||||
};
|
||||
|
||||
class DeviceBase : public std::enable_shared_from_this<DeviceBase>
|
||||
{
|
||||
friend class DeviceToken;
|
||||
friend class HIDDeviceIOKit;
|
||||
friend class HIDDeviceUdev;
|
||||
friend class HIDDeviceWinUSB;
|
||||
friend struct DeviceSignature;
|
||||
|
||||
class DeviceToken* m_token;
|
||||
class IHIDDevice* m_hidDev;
|
||||
std::unique_ptr<IHIDDevice> m_hidDev;
|
||||
void _deviceDisconnected();
|
||||
|
||||
public:
|
||||
DeviceBase(DeviceToken* token);
|
||||
virtual ~DeviceBase();
|
||||
void closeDevice();
|
||||
|
||||
/* Callbacks */
|
||||
virtual void deviceDisconnected()=0;
|
||||
virtual void deviceError(const char* error, ...);
|
||||
|
||||
/* Low-Level API */
|
||||
bool sendUSBInterruptTransfer(const uint8_t* data, size_t length);
|
||||
size_t receiveUSBInterruptTransfer(uint8_t* data, size_t length);
|
||||
virtual void initialCycle() {}
|
||||
virtual void transferCycle() {}
|
||||
virtual void finalCycle() {}
|
||||
virtual size_t getInputBufferSize() const { return 0; }
|
||||
|
||||
/* Low-Level API */
|
||||
bool sendUSBInterruptTransfer(const uint8_t* data, size_t length);
|
||||
size_t receiveUSBInterruptTransfer(uint8_t* data, size_t length);
|
||||
|
||||
/* High-Level API */
|
||||
bool sendHIDReport(const uint8_t* data, size_t length, uint16_t message=0);
|
||||
virtual size_t receiveReport(uint8_t* data, size_t length, uint16_t message=0);
|
||||
bool sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message=0);
|
||||
size_t receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message=0); // Prefer callback version
|
||||
virtual void receivedHIDReport(const uint8_t* /*data*/, size_t /*length*/, HIDReportType /*tp*/, uint32_t /*message*/) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -52,15 +52,15 @@ private:
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
inline bool _insertToken(DeviceToken&& token)
|
||||
inline bool _insertToken(std::unique_ptr<DeviceToken>&& token)
|
||||
{
|
||||
if (DeviceSignature::DeviceMatchToken(token, m_types))
|
||||
if (DeviceSignature::DeviceMatchToken(*token, m_types))
|
||||
{
|
||||
m_tokensLock.lock();
|
||||
TInsertedDeviceToken inseredTok =
|
||||
m_tokens.insert(std::make_pair(token.getDevicePath(), std::move(token)));
|
||||
m_tokens.insert(std::make_pair(token->getDevicePath(), std::move(token)));
|
||||
m_tokensLock.unlock();
|
||||
deviceConnected(inseredTok.first->second);
|
||||
deviceConnected(*inseredTok.first->second);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -70,10 +70,10 @@ private:
|
||||
auto preCheck = m_tokens.find(path);
|
||||
if (preCheck != m_tokens.end())
|
||||
{
|
||||
DeviceToken& tok = preCheck->second;
|
||||
DeviceBase* dev = tok.m_connectedDev;
|
||||
DeviceToken& tok = *preCheck->second;
|
||||
std::shared_ptr<DeviceBase> dev = tok.m_connectedDev;
|
||||
tok._deviceClose();
|
||||
deviceDisconnected(tok, dev);
|
||||
deviceDisconnected(tok, dev.get());
|
||||
m_tokensLock.lock();
|
||||
m_tokens.erase(preCheck);
|
||||
m_tokensLock.unlock();
|
||||
|
||||
@@ -8,26 +8,38 @@
|
||||
namespace boo
|
||||
{
|
||||
|
||||
enum class DeviceType
|
||||
{
|
||||
None = 0,
|
||||
USB = 1,
|
||||
Bluetooth = 2,
|
||||
HID = 3
|
||||
};
|
||||
|
||||
class DeviceToken;
|
||||
class DeviceBase;
|
||||
|
||||
struct DeviceSignature
|
||||
{
|
||||
typedef std::vector<const DeviceSignature*> TDeviceSignatureSet;
|
||||
typedef std::function<DeviceBase*(DeviceToken*)> TFactoryLambda;
|
||||
typedef std::function<std::shared_ptr<DeviceBase>(DeviceToken*)> TFactoryLambda;
|
||||
const char* m_name;
|
||||
std::type_index m_typeIdx;
|
||||
unsigned m_vid, m_pid;
|
||||
TFactoryLambda m_factory;
|
||||
DeviceType m_type;
|
||||
DeviceSignature() : m_name(NULL), m_typeIdx(typeid(DeviceSignature)) {} /* Sentinel constructor */
|
||||
DeviceSignature(const char* name, std::type_index&& typeIdx, unsigned vid, unsigned pid, TFactoryLambda&& factory)
|
||||
: m_name(name), m_typeIdx(typeIdx), m_vid(vid), m_pid(pid), m_factory(factory) {}
|
||||
DeviceSignature(const char* name, std::type_index&& typeIdx, unsigned vid, unsigned pid,
|
||||
TFactoryLambda&& factory, DeviceType type=DeviceType::None)
|
||||
: m_name(name), m_typeIdx(typeIdx), m_vid(vid), m_pid(pid),
|
||||
m_factory(factory), m_type(type) {}
|
||||
static bool DeviceMatchToken(const DeviceToken& token, const TDeviceSignatureSet& sigSet);
|
||||
static DeviceBase* DeviceNew(DeviceToken& token);
|
||||
static std::shared_ptr<DeviceBase> DeviceNew(DeviceToken& token);
|
||||
};
|
||||
|
||||
#define DEVICE_SIG(name, vid, pid) \
|
||||
DeviceSignature(#name, typeid(name), vid, pid, [](DeviceToken* tok) -> DeviceBase* {return new name(tok);})
|
||||
#define DEVICE_SIG(name, vid, pid, type) \
|
||||
DeviceSignature(#name, typeid(name), vid, pid,\
|
||||
[](DeviceToken* tok) -> std::shared_ptr<DeviceBase> {return std::make_shared<name>(tok);}, type)
|
||||
#define DEVICE_SIG_SENTINEL() DeviceSignature()
|
||||
|
||||
extern const DeviceSignature BOO_DEVICE_SIGS[];
|
||||
|
||||
@@ -10,16 +10,7 @@ namespace boo
|
||||
|
||||
class DeviceToken
|
||||
{
|
||||
public:
|
||||
enum class DeviceType
|
||||
{
|
||||
None = 0,
|
||||
USB = 1,
|
||||
Bluetooth = 2,
|
||||
GenericHID = 3
|
||||
};
|
||||
|
||||
private:
|
||||
friend struct DeviceSignature;
|
||||
DeviceType m_devType;
|
||||
unsigned m_vendorId;
|
||||
unsigned m_productId;
|
||||
@@ -28,7 +19,7 @@ private:
|
||||
std::string m_devPath;
|
||||
|
||||
friend class DeviceBase;
|
||||
DeviceBase* m_connectedDev;
|
||||
std::shared_ptr<DeviceBase> m_connectedDev;
|
||||
|
||||
friend class DeviceFinder;
|
||||
inline void _deviceClose()
|
||||
@@ -70,7 +61,7 @@ public:
|
||||
inline const std::string& getProductName() const {return m_productName;}
|
||||
inline const std::string& getDevicePath() const {return m_devPath;}
|
||||
inline bool isDeviceOpen() const {return (m_connectedDev != NULL);}
|
||||
inline DeviceBase* openAndGetDevice()
|
||||
inline std::shared_ptr<DeviceBase> openAndGetDevice()
|
||||
{
|
||||
if (!m_connectedDev)
|
||||
m_connectedDev = DeviceSignature::DeviceNew(*this);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "DeviceBase.hpp"
|
||||
#include "../System.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
||||
@@ -1,8 +1,40 @@
|
||||
#ifndef CDUALSHOCKPAD_HPP
|
||||
#define CDUALSHOCKPAD_HPP
|
||||
#include <stdint.h>
|
||||
#include <type_traits>
|
||||
#include "DeviceBase.hpp"
|
||||
|
||||
#ifndef ENABLE_BITWISE_ENUM
|
||||
#define ENABLE_BITWISE_ENUM(type)\
|
||||
constexpr type operator|(type a, type b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
return type(static_cast<T>(a) | static_cast<T>(b));\
|
||||
}\
|
||||
constexpr type operator&(type a, type b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
return type(static_cast<T>(a) & static_cast<T>(b));\
|
||||
}\
|
||||
inline type& operator|=(type& a, const type& b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
a = type(static_cast<T>(a) | static_cast<T>(b));\
|
||||
return a;\
|
||||
}\
|
||||
inline type& operator&=(type& a, const type& b)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
a = type(static_cast<T>(a) & static_cast<T>(b));\
|
||||
return a;\
|
||||
}\
|
||||
inline type operator~(const type& key)\
|
||||
{\
|
||||
using T = std::underlying_type_t<type>;\
|
||||
return type(~static_cast<T>(key));\
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
||||
@@ -134,6 +166,7 @@ class DualshockPad final : public DeviceBase
|
||||
void initialCycle();
|
||||
void transferCycle();
|
||||
void finalCycle();
|
||||
void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message);
|
||||
public:
|
||||
DualshockPad(DeviceToken* token);
|
||||
~DualshockPad();
|
||||
@@ -179,8 +212,10 @@ public:
|
||||
void setRawLED(int led)
|
||||
{
|
||||
m_report.leds = led;
|
||||
sendHIDReport(m_report.buf, sizeof(m_report), 0x0201);
|
||||
sendHIDReport(m_report.buf, sizeof(m_report), HIDReportType::Output, 0x0201);
|
||||
}
|
||||
|
||||
size_t getInputBufferSize() const { return 49; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace boo
|
||||
{
|
||||
|
||||
typedef std::unordered_map<std::string, DeviceToken> TDeviceTokens;
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<DeviceToken>> TDeviceTokens;
|
||||
typedef std::pair<TDeviceTokens::iterator, bool> TInsertedDeviceToken;
|
||||
class DeviceFinder;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user