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()
|
||||
{
|
||||
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( )
|
||||
|
@ -339,9 +346,9 @@ void FGEventInput::postinit ()
|
|||
|
||||
void FGEventInput::update( double dt )
|
||||
{
|
||||
// call each associated device's update() method
|
||||
for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it )
|
||||
(*it).second->update( dt );
|
||||
for (auto it : input_devices) {
|
||||
it.second->update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
|
||||
|
@ -402,6 +409,7 @@ void FGEventInput::RemoveDevice( unsigned index )
|
|||
|
||||
FGInputDevice *inputDevice = input_devices[index];
|
||||
if (inputDevice) {
|
||||
inputDevice->Close();
|
||||
input_devices.erase(index);
|
||||
delete inputDevice;
|
||||
|
||||
|
|
|
@ -290,6 +290,7 @@ public:
|
|||
virtual void init();
|
||||
virtual void postinit();
|
||||
virtual void update( double dt );
|
||||
virtual void shutdown() override;
|
||||
|
||||
const static unsigned MAX_DEVICES = 1000;
|
||||
const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;
|
||||
|
|
|
@ -153,8 +153,8 @@ public:
|
|||
|
||||
virtual ~FGMacOSXInputDevice();
|
||||
|
||||
void Open();
|
||||
void Close();
|
||||
void Open() override;
|
||||
void Close() override;
|
||||
|
||||
virtual void update(double dt);
|
||||
virtual const char *TranslateEventName(FGEventData &eventData);
|
||||
|
@ -169,7 +169,7 @@ private:
|
|||
void buildElementNameDictionary();
|
||||
|
||||
std::string nameForHIDElement(IOHIDElementRef element) const;
|
||||
|
||||
|
||||
IOHIDDeviceRef _hid;
|
||||
IOHIDQueueRef _queue;
|
||||
FGMacOSXEventInputPrivate* _subsystem;
|
||||
|
@ -227,6 +227,11 @@ void FGMacOSXEventInput::postinit()
|
|||
|
||||
void FGMacOSXEventInput::shutdown()
|
||||
{
|
||||
FGEventInput::shutdown();
|
||||
|
||||
IOHIDManagerRegisterDeviceMatchingCallback(d->hidManager, nullptr, nullptr);
|
||||
IOHIDManagerRegisterDeviceRemovalCallback(d->hidManager, nullptr, nullptr);
|
||||
|
||||
IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone);
|
||||
IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
CFRelease(d->hidManager);
|
||||
|
@ -259,6 +264,12 @@ void FGMacOSXEventInputPrivate::matchedDevice(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
|
||||
}
|
||||
|
||||
|
@ -327,21 +338,16 @@ FGMacOSXInputDevice::FGMacOSXInputDevice(IOHIDDeviceRef hidRef,
|
|||
|
||||
FGMacOSXInputDevice::~FGMacOSXInputDevice()
|
||||
{
|
||||
NameElementDict::iterator it;
|
||||
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
|
||||
CFRelease(it->second);
|
||||
}
|
||||
|
||||
CFRelease(_queue);
|
||||
CFRelease(_hid);
|
||||
}
|
||||
|
||||
void FGMacOSXInputDevice::Open()
|
||||
{
|
||||
|
||||
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
|
||||
|
||||
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
|
||||
|
||||
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
|
@ -431,8 +437,11 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
|
|||
namedElements[os.str()] = namedElements[name];
|
||||
CFRetain(namedElements[os.str()]);
|
||||
}
|
||||
|
||||
}
|
||||
#if 1
|
||||
|
||||
// HID debugging code
|
||||
#if 0
|
||||
NameElementDict::const_iterator it;
|
||||
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
|
||||
int report = IOHIDElementGetReportID(it->second);
|
||||
|
@ -457,15 +466,25 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
|
|||
|
||||
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);
|
||||
IOHIDQueueUnscheduleFromRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
|
||||
IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone);
|
||||
}
|
||||
|
||||
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()) {
|
||||
buildElementNameDictionary();
|
||||
}
|
||||
|
@ -476,6 +495,7 @@ void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
IOHIDQueueAddElement(_queue, it->second);
|
||||
FGInputDevice::AddHandledEvent(handledEvent);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue