2016-05-04 20:00:03 +02:00
|
|
|
// Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
|
|
|
|
// reserved. Use of this source code is governed by a BSD-style license that
|
|
|
|
// can be found in the LICENSE file.
|
|
|
|
|
2016-11-18 00:52:42 +01:00
|
|
|
#include "tests/shared/browser/main_message_loop_external_pump.h"
|
2016-05-04 20:00:03 +02:00
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import <AppKit/AppKit.h>
|
|
|
|
|
|
|
|
#include "include/cef_app.h"
|
|
|
|
|
|
|
|
@class EventHandler;
|
|
|
|
|
|
|
|
namespace client {
|
|
|
|
|
|
|
|
class MainMessageLoopExternalPumpMac : public MainMessageLoopExternalPump {
|
|
|
|
public:
|
|
|
|
MainMessageLoopExternalPumpMac();
|
|
|
|
~MainMessageLoopExternalPumpMac();
|
|
|
|
|
|
|
|
// MainMessageLoopStd methods:
|
|
|
|
void Quit() OVERRIDE;
|
|
|
|
int Run() OVERRIDE;
|
|
|
|
|
|
|
|
// MainMessageLoopExternalPump methods:
|
|
|
|
void OnScheduleMessagePumpWork(int64 delay_ms) OVERRIDE;
|
|
|
|
|
|
|
|
// Internal methods used for processing the event callbacks. They are public
|
|
|
|
// for simplicity but should not be used directly.
|
|
|
|
void HandleScheduleWork(int64 delay_ms);
|
|
|
|
void HandleTimerTimeout();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// MainMessageLoopExternalPump methods:
|
|
|
|
void SetTimer(int64 delay_ms) OVERRIDE;
|
|
|
|
void KillTimer() OVERRIDE;
|
|
|
|
bool IsTimerPending() OVERRIDE { return timer_ != nil; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Owner thread that will run events.
|
|
|
|
NSThread* owner_thread_;
|
|
|
|
|
|
|
|
// Pending work timer.
|
|
|
|
NSTimer* timer_;
|
|
|
|
|
|
|
|
// Used to handle event callbacks on the owner thread.
|
|
|
|
EventHandler* event_handler_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace client
|
|
|
|
|
|
|
|
// Object that handles event callbacks on the owner thread.
|
|
|
|
@interface EventHandler : NSObject {
|
|
|
|
@private
|
|
|
|
client::MainMessageLoopExternalPumpMac* pump_;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id)initWithPump:(client::MainMessageLoopExternalPumpMac*)pump;
|
|
|
|
- (void)scheduleWork:(NSNumber*)delay_ms;
|
|
|
|
- (void)timerTimeout:(id)obj;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation EventHandler
|
|
|
|
|
|
|
|
- (id)initWithPump:(client::MainMessageLoopExternalPumpMac*)pump {
|
|
|
|
if (self = [super init]) {
|
|
|
|
pump_ = pump;
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)scheduleWork:(NSNumber*)delay_ms {
|
|
|
|
pump_->HandleScheduleWork([delay_ms integerValue]);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)timerTimeout:(id)obj {
|
|
|
|
pump_->HandleTimerTimeout();
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
namespace client {
|
|
|
|
|
|
|
|
MainMessageLoopExternalPumpMac::MainMessageLoopExternalPumpMac()
|
|
|
|
: owner_thread_([[NSThread currentThread] retain]),
|
|
|
|
timer_(nil) {
|
|
|
|
event_handler_ = [[[EventHandler alloc] initWithPump:this] retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
MainMessageLoopExternalPumpMac::~MainMessageLoopExternalPumpMac() {
|
|
|
|
KillTimer();
|
|
|
|
[owner_thread_ release];
|
|
|
|
[event_handler_ release];
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainMessageLoopExternalPumpMac::Quit() {
|
|
|
|
[NSApp stop:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
int MainMessageLoopExternalPumpMac::Run() {
|
|
|
|
// Run the message loop.
|
|
|
|
[NSApp run];
|
|
|
|
|
|
|
|
KillTimer();
|
|
|
|
|
|
|
|
// We need to run the message pump until it is idle. However we don't have
|
|
|
|
// that information here so we run the message loop "for a while".
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
// Let default runloop observers run.
|
|
|
|
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, 1);
|
|
|
|
|
|
|
|
// Do some work.
|
|
|
|
CefDoMessageLoopWork();
|
|
|
|
|
|
|
|
// Sleep to allow the CEF proc to do work.
|
|
|
|
[NSThread sleepForTimeInterval: 0.05];
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainMessageLoopExternalPumpMac::OnScheduleMessagePumpWork(int64 delay_ms) {
|
|
|
|
// This method may be called on any thread.
|
|
|
|
NSNumber* number = [NSNumber numberWithInt:static_cast<int>(delay_ms)];
|
|
|
|
[event_handler_ performSelector:@selector(scheduleWork:)
|
|
|
|
onThread:owner_thread_
|
|
|
|
withObject:number
|
|
|
|
waitUntilDone:NO];
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainMessageLoopExternalPumpMac::HandleScheduleWork(int64 delay_ms) {
|
|
|
|
OnScheduleWork(delay_ms);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainMessageLoopExternalPumpMac::HandleTimerTimeout() {
|
|
|
|
OnTimerTimeout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainMessageLoopExternalPumpMac::SetTimer(int64 delay_ms) {
|
|
|
|
DCHECK_GT(delay_ms, 0);
|
|
|
|
DCHECK(!timer_);
|
|
|
|
|
|
|
|
const double delay_s = static_cast<double>(delay_ms) / 1000.0;
|
|
|
|
timer_ = [[NSTimer timerWithTimeInterval: delay_s
|
|
|
|
target: event_handler_
|
|
|
|
selector: @selector(timerTimeout:)
|
|
|
|
userInfo: nil
|
|
|
|
repeats: NO] retain];
|
|
|
|
|
|
|
|
// Add the timer to default and tracking runloop modes.
|
|
|
|
NSRunLoop* owner_runloop = [NSRunLoop currentRunLoop];
|
|
|
|
[owner_runloop addTimer: timer_ forMode: NSRunLoopCommonModes];
|
|
|
|
[owner_runloop addTimer: timer_ forMode: NSEventTrackingRunLoopMode];
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainMessageLoopExternalPumpMac::KillTimer() {
|
|
|
|
if (timer_ != nil) {
|
|
|
|
[timer_ invalidate];
|
|
|
|
[timer_ release];
|
|
|
|
timer_ = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
2016-11-16 21:24:13 +01:00
|
|
|
scoped_ptr<MainMessageLoopExternalPump>
|
2016-05-04 20:00:03 +02:00
|
|
|
MainMessageLoopExternalPump::Create() {
|
2016-11-16 21:24:13 +01:00
|
|
|
return scoped_ptr<MainMessageLoopExternalPump>(
|
2016-05-04 20:00:03 +02:00
|
|
|
new MainMessageLoopExternalPumpMac());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace client
|