|
|
|
@ -66,25 +66,44 @@ static double distantFutureInterval = (double)50*365*24*3600; |
|
|
|
ComPtr<IAvnPlatformThreadingInterfaceEvents> _events; |
|
|
|
bool _wakeupDelegateSent; |
|
|
|
bool _signaled; |
|
|
|
bool _backgroundProcessingRequested; |
|
|
|
CFRunLoopObserverRef _observer; |
|
|
|
CFRunLoopTimerRef _timer; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) checkSignaled |
|
|
|
{ |
|
|
|
bool signaled; |
|
|
|
@synchronized (self) { |
|
|
|
signaled = _signaled; |
|
|
|
_signaled = false; |
|
|
|
} |
|
|
|
if(signaled) |
|
|
|
{ |
|
|
|
_events->Signaled(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
- (Signaler*) init |
|
|
|
{ |
|
|
|
_observer = CFRunLoopObserverCreateWithHandler(nil, |
|
|
|
kCFRunLoopBeforeSources | kCFRunLoopAfterWaiting, |
|
|
|
kCFRunLoopBeforeSources |
|
|
|
| kCFRunLoopAfterWaiting |
|
|
|
| kCFRunLoopBeforeWaiting |
|
|
|
, |
|
|
|
true, 0, |
|
|
|
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { |
|
|
|
bool signaled; |
|
|
|
@synchronized (self) { |
|
|
|
signaled = self->_signaled; |
|
|
|
self->_signaled = false; |
|
|
|
} |
|
|
|
if(signaled) |
|
|
|
if(activity == kCFRunLoopBeforeWaiting) |
|
|
|
{ |
|
|
|
self->_events->Signaled(); |
|
|
|
bool triggerProcessing; |
|
|
|
@synchronized (self) { |
|
|
|
triggerProcessing = self->_backgroundProcessingRequested; |
|
|
|
self->_backgroundProcessingRequested = false; |
|
|
|
} |
|
|
|
if(triggerProcessing) |
|
|
|
self->_events->ReadyForBackgroundProcessing(); |
|
|
|
} |
|
|
|
[self checkSignaled]; |
|
|
|
}); |
|
|
|
CFRunLoopAddObserver(CFRunLoopGetMain(), _observer, kCFRunLoopCommonModes); |
|
|
|
|
|
|
|
@ -135,10 +154,27 @@ static double distantFutureInterval = (double)50*365*24*3600; |
|
|
|
if(_signaled) |
|
|
|
return; |
|
|
|
_signaled = true; |
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{ |
|
|
|
[self checkSignaled]; |
|
|
|
}); |
|
|
|
CFRunLoopWakeUp(CFRunLoopGetMain()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
- (void) requestBackgroundProcessing |
|
|
|
{ |
|
|
|
@synchronized (self) { |
|
|
|
if(_backgroundProcessingRequested) |
|
|
|
return; |
|
|
|
_backgroundProcessingRequested = true; |
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{ |
|
|
|
// This is needed to wakeup the loop if we are called from inside of BeforeWait hook |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@end |
|
|
|
|
|
|
|
|
|
|
|
@ -165,15 +201,7 @@ public: |
|
|
|
return [NSThread isMainThread]; |
|
|
|
}; |
|
|
|
|
|
|
|
bool HasPendingInput() override |
|
|
|
{ |
|
|
|
auto event = [NSApp |
|
|
|
nextEventMatchingMask: NSEventMaskAny |
|
|
|
untilDate:nil |
|
|
|
inMode:NSDefaultRunLoopMode |
|
|
|
dequeue:false]; |
|
|
|
return event != nil; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
void SetEvents(IAvnPlatformThreadingInterfaceEvents *cb) override |
|
|
|
{ |
|
|
|
@ -227,6 +255,11 @@ public: |
|
|
|
[_signaler updateTimer:ms]; |
|
|
|
}; |
|
|
|
|
|
|
|
void RequestBackgroundProcessing() override { |
|
|
|
[_signaler requestBackgroundProcessing]; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
extern IAvnPlatformThreadingInterface* CreatePlatformThreading() |
|
|
|
|