3 #include "fml/logging.h"
8 CFAbsoluteTime target_time;
10 Task(
void (^block)(
void), CFAbsoluteTime target_time) : block(block), target_time(target_time) {}
13 const CFStringRef kFlutterRunLoopMode = CFSTR(
"FlutterRunLoopMode");
20 CFRunLoopRef _runLoop;
26 static void Perform(
void* info) {
28 [runner performExpiredTasks];
31 static void PerformTimer(CFRunLoopTimerRef timer,
void* info) {
33 [runner performExpiredTasks];
36 - (instancetype)init {
37 if (
self = [super init]) {
38 _runLoop = CFRunLoopGetCurrent();
39 CFRunLoopSourceContext sourceContext = {
40 .info = (__bridge
void*)
self,
43 _source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sourceContext);
44 CFRunLoopAddSource(_runLoop,
_source, kCFRunLoopCommonModes);
45 CFRunLoopAddSource(_runLoop,
_source, kFlutterRunLoopMode);
47 CFRunLoopTimerContext timerContext = {
48 .info = (__bridge
void*)
self,
50 _timer = CFRunLoopTimerCreate(kCFAllocatorDefault, HUGE_VALF, HUGE_VALF, 0, 0, PerformTimer,
52 CFRunLoopAddTimer(_runLoop,
_timer, kCFRunLoopCommonModes);
53 CFRunLoopAddTimer(_runLoop,
_timer, kFlutterRunLoopMode);
59 CFRunLoopTimerInvalidate(
_timer);
60 CFRunLoopRemoveTimer(_runLoop,
_timer, kCFRunLoopCommonModes);
61 CFRunLoopRemoveTimer(_runLoop,
_timer, kFlutterRunLoopMode);
62 CFRunLoopSourceInvalidate(
_source);
63 CFRunLoopRemoveSource(_runLoop,
_source, kCFRunLoopCommonModes);
64 CFRunLoopRemoveSource(_runLoop,
_source, kFlutterRunLoopMode);
68 CFAbsoluteTime nextFireTime = HUGE_VALF;
69 for (
const auto& task :
_tasks) {
70 nextFireTime = std::min(nextFireTime, task.target_time);
72 CFRunLoopTimerSetNextFireDate(
_timer, nextFireTime);
75 - (void)performExpiredTasks {
76 std::vector<Task> expiredTasks;
78 CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
79 std::vector<Task>::iterator it =
_tasks.begin();
80 while (it !=
_tasks.end()) {
81 if (it->target_time <= now) {
82 expiredTasks.push_back(std::move(*it));
90 for (
const auto& task : expiredTasks) {
95 - (void)performBlock:(
void (^)(
void))block afterDelay:(NSTimeInterval)delay {
97 _tasks.emplace_back(block, CFAbsoluteTimeGetCurrent() + delay);
101 CFRunLoopSourceSignal(
_source);
102 CFRunLoopWakeUp(_runLoop);
107 - (void)performBlock:(
void (^)(
void))block {
108 [
self performBlock:block afterDelay:0];
111 + (void)ensureMainLoopInitialized {
112 FML_DCHECK(NSRunLoop.currentRunLoop == NSRunLoop.mainRunLoop);
113 if (mainLoop == nil) {
119 FML_DCHECK(mainLoop != nil);
123 - (void)pollFlutterMessagesOnce {
124 CFRunLoopRunInMode(kFlutterRunLoopMode, 0.1, YES);
std::vector< Task > _tasks
CFRunLoopSourceRef _source