Work-around OS-X event-input shutdown crashes.
This commit is contained in:
parent
f61293a935
commit
9441f0d656
3 changed files with 47 additions and 18 deletions
|
@ -321,9 +321,16 @@ FGEventInput::FGEventInput() :
|
||||||
|
|
||||||
FGEventInput::~FGEventInput()
|
FGEventInput::~FGEventInput()
|
||||||
{
|
{
|
||||||
for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it )
|
|
||||||
delete (*it).second;
|
}
|
||||||
input_devices.clear();
|
|
||||||
|
void FGEventInput::shutdown()
|
||||||
|
{
|
||||||
|
for (auto it : input_devices) {
|
||||||
|
it.second->Close();
|
||||||
|
delete it.second;
|
||||||
|
}
|
||||||
|
input_devices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGEventInput::init( )
|
void FGEventInput::init( )
|
||||||
|
@ -339,9 +346,9 @@ void FGEventInput::postinit ()
|
||||||
|
|
||||||
void FGEventInput::update( double dt )
|
void FGEventInput::update( double dt )
|
||||||
{
|
{
|
||||||
// call each associated device's update() method
|
for (auto it : input_devices) {
|
||||||
for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it )
|
it.second->update(dt);
|
||||||
(*it).second->update( dt );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
|
unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
|
||||||
|
@ -402,6 +409,7 @@ void FGEventInput::RemoveDevice( unsigned index )
|
||||||
|
|
||||||
FGInputDevice *inputDevice = input_devices[index];
|
FGInputDevice *inputDevice = input_devices[index];
|
||||||
if (inputDevice) {
|
if (inputDevice) {
|
||||||
|
inputDevice->Close();
|
||||||
input_devices.erase(index);
|
input_devices.erase(index);
|
||||||
delete inputDevice;
|
delete inputDevice;
|
||||||
|
|
||||||
|
|
|
@ -290,6 +290,7 @@ public:
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void postinit();
|
virtual void postinit();
|
||||||
virtual void update( double dt );
|
virtual void update( double dt );
|
||||||
|
virtual void shutdown() override;
|
||||||
|
|
||||||
const static unsigned MAX_DEVICES = 1000;
|
const static unsigned MAX_DEVICES = 1000;
|
||||||
const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;
|
const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;
|
||||||
|
|
|
@ -153,8 +153,8 @@ public:
|
||||||
|
|
||||||
virtual ~FGMacOSXInputDevice();
|
virtual ~FGMacOSXInputDevice();
|
||||||
|
|
||||||
void Open();
|
void Open() override;
|
||||||
void Close();
|
void Close() override;
|
||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
virtual const char *TranslateEventName(FGEventData &eventData);
|
virtual const char *TranslateEventName(FGEventData &eventData);
|
||||||
|
@ -169,7 +169,7 @@ private:
|
||||||
void buildElementNameDictionary();
|
void buildElementNameDictionary();
|
||||||
|
|
||||||
std::string nameForHIDElement(IOHIDElementRef element) const;
|
std::string nameForHIDElement(IOHIDElementRef element) const;
|
||||||
|
|
||||||
IOHIDDeviceRef _hid;
|
IOHIDDeviceRef _hid;
|
||||||
IOHIDQueueRef _queue;
|
IOHIDQueueRef _queue;
|
||||||
FGMacOSXEventInputPrivate* _subsystem;
|
FGMacOSXEventInputPrivate* _subsystem;
|
||||||
|
@ -227,6 +227,11 @@ void FGMacOSXEventInput::postinit()
|
||||||
|
|
||||||
void FGMacOSXEventInput::shutdown()
|
void FGMacOSXEventInput::shutdown()
|
||||||
{
|
{
|
||||||
|
FGEventInput::shutdown();
|
||||||
|
|
||||||
|
IOHIDManagerRegisterDeviceMatchingCallback(d->hidManager, nullptr, nullptr);
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback(d->hidManager, nullptr, nullptr);
|
||||||
|
|
||||||
IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone);
|
IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone);
|
||||||
IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||||
CFRelease(d->hidManager);
|
CFRelease(d->hidManager);
|
||||||
|
@ -259,6 +264,12 @@ void FGMacOSXEventInputPrivate::matchedDevice(IOHIDDeviceRef device)
|
||||||
|
|
||||||
void FGMacOSXEventInputPrivate::removedDevice(IOHIDDeviceRef device)
|
void FGMacOSXEventInputPrivate::removedDevice(IOHIDDeviceRef device)
|
||||||
{
|
{
|
||||||
|
std::string productName = getDeviceStringProperty(device, CFSTR(kIOHIDProductKey));
|
||||||
|
std::string manufacturer = getDeviceStringProperty(device, CFSTR(kIOHIDManufacturerKey));
|
||||||
|
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "removed device:" << productName << " from " << manufacturer);
|
||||||
|
|
||||||
|
|
||||||
// see if we have an entry for the device
|
// see if we have an entry for the device
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,21 +338,16 @@ FGMacOSXInputDevice::FGMacOSXInputDevice(IOHIDDeviceRef hidRef,
|
||||||
|
|
||||||
FGMacOSXInputDevice::~FGMacOSXInputDevice()
|
FGMacOSXInputDevice::~FGMacOSXInputDevice()
|
||||||
{
|
{
|
||||||
NameElementDict::iterator it;
|
|
||||||
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
|
|
||||||
CFRelease(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFRelease(_queue);
|
CFRelease(_queue);
|
||||||
CFRelease(_hid);
|
CFRelease(_hid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGMacOSXInputDevice::Open()
|
void FGMacOSXInputDevice::Open()
|
||||||
{
|
{
|
||||||
|
|
||||||
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
|
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
|
||||||
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||||
|
|
||||||
|
|
||||||
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
|
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
|
||||||
|
|
||||||
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||||
|
@ -431,8 +437,11 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
|
||||||
namedElements[os.str()] = namedElements[name];
|
namedElements[os.str()] = namedElements[name];
|
||||||
CFRetain(namedElements[os.str()]);
|
CFRetain(namedElements[os.str()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
|
// HID debugging code
|
||||||
|
#if 0
|
||||||
NameElementDict::const_iterator it;
|
NameElementDict::const_iterator it;
|
||||||
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
|
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
|
||||||
int report = IOHIDElementGetReportID(it->second);
|
int report = IOHIDElementGetReportID(it->second);
|
||||||
|
@ -457,15 +466,25 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
|
||||||
|
|
||||||
void FGMacOSXInputDevice::Close()
|
void FGMacOSXInputDevice::Close()
|
||||||
{
|
{
|
||||||
|
// leaking these otherwise we get a crash shutting down the HID-manager
|
||||||
|
// object. Don't understand why that should be the case
|
||||||
|
#if 0
|
||||||
|
for (auto it : namedElements) {
|
||||||
|
CFRelease(it.second);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
namedElements.clear();
|
||||||
|
|
||||||
IOHIDQueueStop(_queue);
|
IOHIDQueueStop(_queue);
|
||||||
|
IOHIDQueueUnscheduleFromRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||||
|
|
||||||
IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||||
IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone);
|
IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
|
void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "adding event:" << handledEvent->GetName());
|
SG_LOG(SG_INPUT, SG_DEBUG, "adding event:" << handledEvent->GetName());
|
||||||
|
|
||||||
if (namedElements.empty()) {
|
if (namedElements.empty()) {
|
||||||
buildElementNameDictionary();
|
buildElementNameDictionary();
|
||||||
}
|
}
|
||||||
|
@ -476,6 +495,7 @@ void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IOHIDQueueAddElement(_queue, it->second);
|
IOHIDQueueAddElement(_queue, it->second);
|
||||||
FGInputDevice::AddHandledEvent(handledEvent);
|
FGInputDevice::AddHandledEvent(handledEvent);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue