///////////////////////////////////////////////////////
| 392 | |
| 393 | //////////////////////////////////////////////////////////// |
| 394 | JoystickState JoystickImpl::update() |
| 395 | { |
| 396 | const AutoreleasePool pool; |
| 397 | static constexpr JoystickState disconnectedState; // return this if joystick was disconnected |
| 398 | JoystickState state; // otherwise return that |
| 399 | state.connected = true; |
| 400 | |
| 401 | // Note: free up is done in close() which is called, if required, |
| 402 | // by the joystick manager. So we don't release buttons nor axes here. |
| 403 | |
| 404 | // First, let's determine if the joystick is still connected |
| 405 | const Location selfLoc = m_locationIDs[m_index]; |
| 406 | |
| 407 | // Get all devices |
| 408 | CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks(); |
| 409 | if (devices == nullptr) |
| 410 | return disconnectedState; |
| 411 | |
| 412 | // Get a usable copy of the joysticks devices. |
| 413 | const CFIndex joysticksCount = CFSetGetCount(devices); |
| 414 | std::vector<CFTypeRef> devicesArray(static_cast<std::size_t>(joysticksCount)); |
| 415 | CFSetGetValues(devices, devicesArray.data()); |
| 416 | |
| 417 | // Search for it |
| 418 | bool found = false; |
| 419 | for (CFIndex i(0); !found && i < joysticksCount; ++i) |
| 420 | { |
| 421 | auto* d = static_cast<IOHIDDeviceRef>(const_cast<void*>(devicesArray[static_cast<std::size_t>(i)])); |
| 422 | if (selfLoc == HIDInputManager::getLocationID(d)) |
| 423 | found = true; |
| 424 | } |
| 425 | |
| 426 | // Release unused stuff |
| 427 | CFRelease(devices); |
| 428 | |
| 429 | // If not found we consider it disconnected |
| 430 | if (!found) |
| 431 | return disconnectedState; |
| 432 | |
| 433 | // Update buttons' state |
| 434 | unsigned int i = 0; |
| 435 | for (auto it = m_buttons.begin(); it != m_buttons.end(); ++it, ++i) |
| 436 | { |
| 437 | IOHIDValueRef value = nil; |
| 438 | IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value); |
| 439 | |
| 440 | // Check for plug out. |
| 441 | if (!value) |
| 442 | { |
| 443 | return disconnectedState; |
| 444 | } |
| 445 | |
| 446 | // 1 means pressed, others mean released |
| 447 | state.buttons[i] = IOHIDValueGetIntegerValue(value) == 1; |
| 448 | } |
| 449 | |
| 450 | // Update axes' state |
| 451 | for (const auto& [axis, iohidElementRef] : m_axis) |
nothing calls this directly
no test coverage detected