Modernize more CF pointers

This commit is contained in:
Chris Thrasher 2024-07-15 13:58:30 -06:00
parent def8d7645b
commit 35653dacc5
No known key found for this signature in database
GPG Key ID: 56FB686C9DFC8E2C
4 changed files with 28 additions and 61 deletions

View File

@ -41,7 +41,7 @@
namespace sf::priv namespace sf::priv
{ {
using IOHIDElements = std::vector<IOHIDElementRef>; using IOHIDElements = std::vector<CFPtr<__IOHIDElement>>;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief sf::priv::InputImpl helper /// \brief sf::priv::InputImpl helper

View File

@ -796,7 +796,7 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
if (code != Keyboard::Scan::Unknown) if (code != Keyboard::Scan::Unknown)
{ {
CFRetain(key); CFRetain(key);
m_keys[code].push_back(key); m_keys[code].emplace_back(key);
} }
} }
@ -920,15 +920,8 @@ void HIDInputManager::freeUp()
m_manager.reset(); m_manager.reset();
if (m_keysInitialized) if (m_keysInitialized)
{
for (auto& key : m_keys) for (auto& key : m_keys)
{
for (IOHIDElementRef iohidElementRef : key)
CFRelease(iohidElementRef);
key.clear(); key.clear();
}
}
m_keysInitialized = false; m_keysInitialized = false;
} }
@ -961,13 +954,12 @@ bool HIDInputManager::isPressed(IOHIDElements& elements) const
{ {
IOHIDValueRef value = nil; IOHIDValueRef value = nil;
IOHIDDeviceRef device = IOHIDElementGetDevice(*it); IOHIDDeviceRef device = IOHIDElementGetDevice(it->get());
IOHIDDeviceGetValue(device, *it, &value); IOHIDDeviceGetValue(device, it->get(), &value);
if (!value) if (!value)
{ {
// This means some kind of error / disconnection so we remove this element from our database. // This means some kind of error / disconnection so we remove this element from our database.
CFRelease(*it);
it = elements.erase(it); it = elements.erase(it);
} }
else else

View File

@ -218,11 +218,12 @@ bool JoystickImpl::open(unsigned int index)
const CFIndex elementsCount = CFArrayGetCount(elements.get()); const CFIndex elementsCount = CFArrayGetCount(elements.get());
for (int i = 0; i < elementsCount; ++i) for (int i = 0; i < elementsCount; ++i)
{ {
auto* element = static_cast<IOHIDElementRef>(const_cast<void*>(CFArrayGetValueAtIndex(elements.get(), i))); auto element = std::shared_ptr(CFPtr<__IOHIDElement>(
switch (IOHIDElementGetUsagePage(element)) static_cast<IOHIDElementRef>(const_cast<void*>(CFArrayGetValueAtIndex(elements.get(), i)))));
switch (IOHIDElementGetUsagePage(element.get()))
{ {
case kHIDPage_GenericDesktop: case kHIDPage_GenericDesktop:
switch (IOHIDElementGetUsage(element)) switch (IOHIDElementGetUsage(element.get()))
{ {
case kHIDUsage_GD_X: case kHIDUsage_GD_X:
m_axis[Joystick::Axis::X] = element; m_axis[Joystick::Axis::X] = element;
@ -255,8 +256,8 @@ bool JoystickImpl::open(unsigned int index)
// We assume this model here as well. Hence, with 4 switches and intermediate // We assume this model here as well. Hence, with 4 switches and intermediate
// positions we have 8 values (0-7) plus the "null" state (8). // positions we have 8 values (0-7) plus the "null" state (8).
{ {
const CFIndex min = IOHIDElementGetLogicalMin(element); const CFIndex min = IOHIDElementGetLogicalMin(element.get());
const CFIndex max = IOHIDElementGetLogicalMax(element); const CFIndex max = IOHIDElementGetLogicalMax(element.get());
if (min != 0 || max != 7) if (min != 0 || max != 7)
{ {
@ -275,18 +276,18 @@ bool JoystickImpl::open(unsigned int index)
// We assume a game pad is an application collection, meaning it doesn't hold // We assume a game pad is an application collection, meaning it doesn't hold
// any values per say. They kind of "emit" the joystick's usages. // any values per say. They kind of "emit" the joystick's usages.
// See §3.4.3 Usage Types (Collection) of HUT v1.12 // See §3.4.3 Usage Types (Collection) of HUT v1.12
if (IOHIDElementGetCollectionType(element) != kIOHIDElementCollectionTypeApplication) if (IOHIDElementGetCollectionType(element.get()) != kIOHIDElementCollectionTypeApplication)
{ {
sf::err() << std::hex << "Gamepage (vendor/product id: 0x" << m_identification.vendorId sf::err() << std::hex << "Gamepage (vendor/product id: 0x" << m_identification.vendorId
<< "/0x" << m_identification.productId << ") is not an CA but a 0x" << "/0x" << m_identification.productId << ") is not an CA but a 0x"
<< IOHIDElementGetCollectionType(element) << std::dec << std::endl; << IOHIDElementGetCollectionType(element.get()) << std::dec << std::endl;
} }
break; break;
default: default:
#ifdef SFML_DEBUG #ifdef SFML_DEBUG
sf::err() << "Unexpected usage for element of Page Generic Desktop: 0x" << std::hex sf::err() << "Unexpected usage for element of Page Generic Desktop: 0x" << std::hex
<< IOHIDElementGetUsage(element) << std::dec << std::endl; << IOHIDElementGetUsage(element.get()) << std::dec << std::endl;
#endif #endif
break; break;
} }
@ -307,21 +308,7 @@ bool JoystickImpl::open(unsigned int index)
// HID Usage (assigned by manufacturer and/or a driver). // HID Usage (assigned by manufacturer and/or a driver).
std::sort(m_buttons.begin(), std::sort(m_buttons.begin(),
m_buttons.end(), m_buttons.end(),
[](IOHIDElementRef b1, IOHIDElementRef b2) { return IOHIDElementGetUsage(b1) < IOHIDElementGetUsage(b2); }); [](auto b1, auto b2) { return IOHIDElementGetUsage(b1.get()) < IOHIDElementGetUsage(b2.get()); });
// Retain all these objects for personal use
for (IOHIDElementRef iohidElementRef : m_buttons)
CFRetain(iohidElementRef);
for (const auto& [axis, iohidElementRef] : m_axis)
CFRetain(iohidElementRef);
if (m_hat != nullptr)
CFRetain(m_hat);
// Note: we didn't retain element in the switch because we might have multiple
// Axis X (for example) and we want to keep only the last one. To prevent
// leaking we retain objects 'only' now.
return true; return true;
} }
@ -332,20 +319,9 @@ void JoystickImpl::close()
{ {
const AutoreleasePool pool; const AutoreleasePool pool;
for (IOHIDElementRef iohidElementRef : m_buttons)
CFRelease(iohidElementRef);
m_buttons.clear(); m_buttons.clear();
for (const auto& [axis, iohidElementRef] : m_axis)
CFRelease(iohidElementRef);
m_axis.clear(); m_axis.clear();
m_hat.reset();
if (m_hat != nullptr)
CFRelease(m_hat);
m_hat = nullptr;
// And we unregister this joystick // And we unregister this joystick
m_locationIDs[m_index] = 0; m_locationIDs[m_index] = 0;
@ -418,11 +394,10 @@ JoystickState JoystickImpl::update()
return disconnectedState; return disconnectedState;
// Update buttons' state // Update buttons' state
unsigned int i = 0; for (std::size_t i = 0; i < m_buttons.size(); ++i)
for (auto it = m_buttons.begin(); it != m_buttons.end(); ++it, ++i)
{ {
IOHIDValueRef value = nil; IOHIDValueRef value = nil;
IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value); IOHIDDeviceGetValue(IOHIDElementGetDevice(m_buttons[i].get()), m_buttons[i].get(), &value);
// Check for plug out. // Check for plug out.
if (!value) if (!value)
@ -438,7 +413,7 @@ JoystickState JoystickImpl::update()
for (const auto& [axis, iohidElementRef] : m_axis) for (const auto& [axis, iohidElementRef] : m_axis)
{ {
IOHIDValueRef value = nil; IOHIDValueRef value = nil;
IOHIDDeviceGetValue(IOHIDElementGetDevice(iohidElementRef), iohidElementRef, &value); IOHIDDeviceGetValue(IOHIDElementGetDevice(iohidElementRef.get()), iohidElementRef.get(), &value);
// Check for plug out. // Check for plug out.
if (!value) if (!value)
@ -456,8 +431,8 @@ JoystickState JoystickImpl::update()
// This method might not be very accurate (the "0 position" can be // This method might not be very accurate (the "0 position" can be
// slightly shift with some device) but we don't care because most // slightly shift with some device) but we don't care because most
// of devices are so sensitive that this is not relevant. // of devices are so sensitive that this is not relevant.
const auto physicalMax = static_cast<double>(IOHIDElementGetPhysicalMax(iohidElementRef)); const auto physicalMax = static_cast<double>(IOHIDElementGetPhysicalMax(iohidElementRef.get()));
const auto physicalMin = static_cast<double>(IOHIDElementGetPhysicalMin(iohidElementRef)); const auto physicalMin = static_cast<double>(IOHIDElementGetPhysicalMin(iohidElementRef.get()));
const double scaledMin = -100; const double scaledMin = -100;
const double scaledMax = 100; const double scaledMax = 100;
const double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical); const double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
@ -475,7 +450,7 @@ JoystickState JoystickImpl::update()
if (m_hat != nullptr) if (m_hat != nullptr)
{ {
IOHIDValueRef value = nil; IOHIDValueRef value = nil;
IOHIDDeviceGetValue(IOHIDElementGetDevice(m_hat), m_hat, &value); IOHIDDeviceGetValue(IOHIDElementGetDevice(m_hat.get()), m_hat.get(), &value);
// Check for plug out. // Check for plug out.
if (!value) if (!value)

View File

@ -111,11 +111,11 @@ private:
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
using Location = long; using Location = long;
using AxisMap = std::unordered_map<Joystick::Axis, IOHIDElementRef>; using AxisMap = std::unordered_map<Joystick::Axis, std::shared_ptr<__IOHIDElement>>;
using ButtonsVector = std::vector<IOHIDElementRef>; using ButtonsVector = std::vector<std::shared_ptr<__IOHIDElement>>;
AxisMap m_axis; ///< Axes (but not POV/Hat) of the joystick AxisMap m_axis; ///< Axes (but not POV/Hat) of the joystick
IOHIDElementRef m_hat{}; ///< POV/Hat axis of the joystick std::shared_ptr<__IOHIDElement> m_hat; ///< POV/Hat axis of the joystick
ButtonsVector m_buttons; ///< Buttons of the joystick ButtonsVector m_buttons; ///< Buttons of the joystick
unsigned int m_index{}; ///< SFML index unsigned int m_index{}; ///< SFML index
Joystick::Identification m_identification; ///< Joystick identification Joystick::Identification m_identification; ///< Joystick identification