mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-13 18:16:20 +01:00
019611c764
Under ARC (Automatic Reference Counting), assigning to an Objective-C pointer has different semantics than assigning to a void* pointer. This makes it dangerous to treat the same memory address as an Objective-C pointer in some cases and as a "regular C pointer" in other cases. This change removes the conditional type defines and instead uses void* everywhere. Explicit type casting in combination with ARC annotations makes it safe to get typed Objective-C pointers from the void* pointers. This change enables ARC by default in the CEF binary distribution CMake configuration for the cefclient and cefsimple sample applications. It can be disabled by adding `-DOPTION_USE_ARC=Off` to the CMake command line. ARC is not supported when building Chromium due to the substantial number of changes that would be required in the Chromium code base.
182 lines
4.8 KiB
Plaintext
182 lines
4.8 KiB
Plaintext
// 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.
|
|
|
|
#include "tests/shared/browser/main_message_loop_external_pump.h"
|
|
|
|
#import <AppKit/AppKit.h>
|
|
#import <Foundation/Foundation.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]), timer_(nil) {
|
|
#if !__has_feature(objc_arc)
|
|
[owner_thread_ retain];
|
|
#endif // !__has_feature(objc_arc)
|
|
event_handler_ = [[EventHandler alloc] initWithPump:this];
|
|
}
|
|
|
|
MainMessageLoopExternalPumpMac::~MainMessageLoopExternalPumpMac() {
|
|
KillTimer();
|
|
#if !__has_feature(objc_arc)
|
|
[owner_thread_ release];
|
|
[event_handler_ release];
|
|
#endif // !__has_feature(objc_arc)
|
|
owner_thread_ = nil;
|
|
event_handler_ = nil;
|
|
}
|
|
|
|
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];
|
|
#if !__has_feature(objc_arc)
|
|
[timer_ retain];
|
|
#endif // !__has_feature(objc_arc)
|
|
|
|
// 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];
|
|
#if !__has_feature(objc_arc)
|
|
[timer_ release];
|
|
#endif // !__has_feature(objc_arc)
|
|
timer_ = nil;
|
|
}
|
|
}
|
|
|
|
// static
|
|
scoped_ptr<MainMessageLoopExternalPump> MainMessageLoopExternalPump::Create() {
|
|
return scoped_ptr<MainMessageLoopExternalPump>(
|
|
new MainMessageLoopExternalPumpMac());
|
|
}
|
|
|
|
} // namespace client
|