Skip to content

Commit a9c759c

Browse files
committed
[iOS] Create FlutterFMLTaskRunner(s)
fml::TaskRunner is a core C++ dependency for asynchronous task execution across the iOS embedder. It appears frequently in Objective-C API which is problematic for adding or migrating embedder code to Swift. This class also makes heavy use of fml::TimePoint and fml::TimeDelta, and thus adds further C++ to any code making use of the task runner. flutter::TaskRunners, is a container that groups together task runners for the platform thread, UI thread, and raster thread. This adds FlutterFMLTaskRunner and FlutterFMLTaskRunners. Ideally, these would be named FlutterTaskRunner but that identifier is already a key part of the Embedder API. To differentiate our FML-based run loops from the Embedder API types, we add FML to the name. The two new classes have API that is entirely free from C++ types, but for each, we introduce a category on it in the FlutterTaskRunner[s]+FML.h header that includes an initialiser that takes the associated C++ type and a getter that returns it. This allows for a stepwise migration. This patch adds, but does not yet migrate to, the new wrapper types. I'll send follow-up patches with the migrations.
1 parent 2321c7e commit a9c759c

12 files changed

Lines changed: 361 additions & 3 deletions

engine/src/flutter/shell/platform/darwin/ios/BUILD.gn

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,12 @@ source_set("InternalFlutterSwift") {
4545
# Targets should only ever depend on the framework target.
4646
# This allows code in this target to use types declared in the bridging
4747
# header, but defined in the framework, while avoiding linking errors.
48-
visibility = [ ":flutter_framework_source" ]
48+
visibility = [
49+
":flutter_framework_source",
50+
":ios_test_flutter",
51+
]
4952
configs += [ "//flutter/shell/platform/darwin/common:config" ]
53+
deps = [ ":flutter_engine_bindings" ]
5054
include_dirs = [
5155
"//flutter/shell/platform/darwin/common/framework/Headers",
5256
"//flutter/shell/platform/darwin/ios/framework/Headers",
@@ -212,23 +216,52 @@ source_set("flutter_framework_source") {
212216
"//flutter/third_party/icu",
213217
"//flutter/third_party/spring_animation",
214218
]
215-
public_deps = [ ":InternalFlutterSwift" ]
219+
public_deps = [
220+
":InternalFlutterSwift",
221+
":flutter_engine_bindings",
222+
]
216223
}
217224

218225
if (enable_ios_unittests) {
226+
source_set("flutter_engine_bindings_test_helpers") {
227+
testonly = true
228+
visibility = [ ":*" ]
229+
configs += [ "//flutter/shell/platform/darwin/common:test_config" ]
230+
sources = [
231+
"framework/Source/FlutterFMLTaskRunnerTestHelper.h",
232+
"framework/Source/FlutterFMLTaskRunnerTestHelper.mm",
233+
]
234+
deps = [
235+
":flutter_engine_bindings",
236+
"//flutter/fml",
237+
]
238+
}
239+
219240
source_set("ios_test_flutter_swift") {
220241
testonly = true
221242
visibility = [ ":*" ]
222243
configs += [ "//flutter/shell/platform/darwin/common:test_config" ]
244+
include_dirs = [
245+
"//flutter/shell/platform/darwin/common/framework/Headers",
246+
"//flutter/shell/platform/darwin/ios/framework/Headers",
247+
"//flutter/shell/platform/darwin/ios/framework",
248+
]
249+
bridge_header = "FlutterTests-Bridging-Header.h"
223250
sources = [
224251
"framework/Source/AccessibilityFeaturesTests.swift",
225252
"framework/Source/ConnectionCollectionTest.swift",
226253
"framework/Source/FakeUIPressProxy.swift",
227254
"framework/Source/LaunchEngineTest.swift",
228255
"framework/Source/SplashScreenManagerTests.swift",
256+
"framework/Source/TaskRunnerTests.swift",
229257
]
230258
frameworks = [ "XCTest.framework" ]
231-
deps = [ ":flutter_framework_source" ]
259+
deps = [
260+
":flutter_engine_bindings",
261+
":flutter_framework_source",
262+
":flutter_engine_bindings_test_helpers",
263+
"//flutter/fml",
264+
]
232265
}
233266

234267
shared_library("ios_test_flutter") {
@@ -291,6 +324,8 @@ if (enable_ios_unittests) {
291324
"platform_view_ios_test.mm",
292325
]
293326
deps = [
327+
":InternalFlutterSwift",
328+
":flutter_engine_bindings_test_helpers",
294329
":flutter_framework",
295330
":flutter_framework_source",
296331
":ios_gpu_configuration",
@@ -314,6 +349,34 @@ if (enable_ios_unittests) {
314349
}
315350
} # if (enable_ios_unittests)
316351

352+
source_set("flutter_engine_bindings") {
353+
visibility = [ ":*" ]
354+
cflags_objc = flutter_cflags_objc
355+
cflags_objcc = flutter_cflags_objcc
356+
357+
defines = [ "FLUTTER_FRAMEWORK=1" ]
358+
configs += [ "//flutter/shell/platform/darwin/common:config" ]
359+
include_dirs = [
360+
"//flutter/shell/platform/darwin/common/framework/Headers",
361+
"//flutter/shell/platform/darwin/ios/framework/Headers",
362+
"//flutter/shell/platform/darwin/ios/framework", # For module.modulemap
363+
]
364+
sources = [
365+
"framework/Source/FlutterFMLTaskRunner+FML.h",
366+
"framework/Source/FlutterFMLTaskRunner.h",
367+
"framework/Source/FlutterFMLTaskRunner.mm",
368+
"framework/Source/FlutterFMLTaskRunners.h",
369+
"framework/Source/FlutterFMLTaskRunners.mm",
370+
]
371+
deps = [
372+
"//flutter/common",
373+
"//flutter/fml",
374+
"//flutter/shell/common",
375+
"//flutter/shell/platform/darwin/common:framework_common",
376+
]
377+
public_deps = [ "//flutter/third_party/spring_animation" ]
378+
}
379+
317380
shared_library("create_flutter_framework_dylib") {
318381
visibility = [ ":*" ]
319382

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FLUTTERTESTS_BRIDGING_HEADER_H_
6+
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FLUTTERTESTS_BRIDGING_HEADER_H_
7+
8+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner.h"
9+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunnerTestHelper.h"
10+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunners.h"
11+
12+
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FLUTTERTESTS_BRIDGING_HEADER_H_

engine/src/flutter/shell/platform/darwin/ios/InternalFlutterSwift-Bridging-Header.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_INTERNALFLUTTERSWIFT_BRIDGING_HEADER_H_
77

88
#import "flutter/shell/platform/darwin/ios/framework/Headers/Flutter.h"
9+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner.h"
10+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunners.h"
911

1012
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_INTERNALFLUTTERSWIFT_BRIDGING_HEADER_H_
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNER_FML_H_
6+
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNER_FML_H_
7+
8+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner.h"
9+
10+
#include "flutter/fml/memory/ref_ptr.h"
11+
#include "flutter/fml/task_runner.h"
12+
13+
@interface FlutterFMLTaskRunner ()
14+
15+
- (instancetype)initWithTaskRunner:(fml::RefPtr<fml::TaskRunner>)task_runner;
16+
17+
- (fml::RefPtr<fml::TaskRunner>)taskRunner;
18+
19+
@end
20+
21+
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNER_FML_H_
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNER_H_
6+
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNER_H_
7+
8+
#import <Foundation/Foundation.h>
9+
10+
NS_SWIFT_NAME(TaskRunner)
11+
@interface FlutterFMLTaskRunner : NSObject
12+
13+
- (void)postTask:(void (^)(void))task;
14+
- (void)runNowOrPostTask:(void (^)(void))task;
15+
- (void)postDelayedTask:(void (^)(void))task delay:(NSTimeInterval)delay;
16+
17+
- (BOOL)runsTasksOnCurrentThread;
18+
19+
@end
20+
21+
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNER_H_
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner+FML.h"
6+
7+
#include <utility>
8+
9+
#include "flutter/fml/logging.h"
10+
11+
@implementation FlutterFMLTaskRunner {
12+
fml::RefPtr<fml::TaskRunner> _taskRunner;
13+
}
14+
15+
- (instancetype)initWithTaskRunner:(fml::RefPtr<fml::TaskRunner>)task_runner {
16+
FML_DCHECK(task_runner);
17+
if (self = [super init]) {
18+
_taskRunner = std::move(task_runner);
19+
}
20+
return self;
21+
}
22+
23+
- (void)postTask:(void (^)(void))task {
24+
FML_DCHECK(task);
25+
_taskRunner->PostTask([task]() { task(); });
26+
}
27+
28+
- (void)runNowOrPostTask:(void (^)(void))task {
29+
FML_DCHECK(task);
30+
fml::TaskRunner::RunNowOrPostTask(_taskRunner, [task]() { task(); });
31+
}
32+
33+
- (void)postDelayedTask:(void (^)(void))task delay:(NSTimeInterval)delay {
34+
FML_DCHECK(task);
35+
_taskRunner->PostDelayedTask([task]() { task(); }, fml::TimeDelta::FromSecondsF(delay));
36+
}
37+
38+
- (BOOL)runsTasksOnCurrentThread {
39+
return _taskRunner->RunsTasksOnCurrentThread();
40+
}
41+
42+
- (fml::RefPtr<fml::TaskRunner>)taskRunner {
43+
return _taskRunner;
44+
}
45+
46+
@end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERTESTHELPER_H_
6+
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERTESTHELPER_H_
7+
8+
#import <Foundation/Foundation.h>
9+
10+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner.h"
11+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunners.h"
12+
13+
NS_ASSUME_NONNULL_BEGIN
14+
15+
@interface FlutterFMLTaskRunnerTestHelper : NSObject
16+
17+
/**
18+
* Returns a FlutterFMLTaskRunner for the current thread.
19+
*/
20+
+ (FlutterFMLTaskRunner*)makeCurrentThreadTaskRunner;
21+
22+
/**
23+
* Returns a FlutterFMLTaskRunners object where all runners point to the same task runner.
24+
*/
25+
+ (FlutterFMLTaskRunners*)makeTaskRunnersWithLabel:(NSString*)label
26+
taskRunner:(FlutterFMLTaskRunner*)taskRunner;
27+
28+
@end
29+
30+
NS_ASSUME_NONNULL_END
31+
32+
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERTESTHELPER_H_
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunnerTestHelper.h"
6+
7+
#include "flutter/fml/message_loop.h"
8+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner+FML.h"
9+
10+
@implementation FlutterFMLTaskRunnerTestHelper
11+
12+
+ (FlutterFMLTaskRunner*)makeCurrentThreadTaskRunner {
13+
fml::MessageLoop::EnsureInitializedForCurrentThread();
14+
return [[FlutterFMLTaskRunner alloc]
15+
initWithTaskRunner:fml::MessageLoop::GetCurrent().GetTaskRunner()];
16+
}
17+
18+
+ (FlutterFMLTaskRunners*)makeTaskRunnersWithLabel:(NSString*)label
19+
taskRunner:(FlutterFMLTaskRunner*)taskRunner {
20+
return [[FlutterFMLTaskRunners alloc] initWithLabel:label
21+
platformTaskRunner:taskRunner
22+
rasterTaskRunner:taskRunner
23+
uiTaskRunner:taskRunner
24+
ioTaskRunner:taskRunner];
25+
}
26+
27+
@end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERS_FML_H_
6+
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERS_FML_H_
7+
8+
#include "flutter/common/task_runners.h"
9+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunners.h"
10+
11+
@interface FlutterFMLTaskRunners (FML)
12+
13+
@property(nonatomic, readonly) const flutter::TaskRunners& taskRunners;
14+
15+
@end
16+
17+
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERS_FML_H_
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERS_H_
6+
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERS_H_
7+
8+
#import <Foundation/Foundation.h>
9+
10+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFMLTaskRunner.h"
11+
12+
NS_ASSUME_NONNULL_BEGIN
13+
14+
NS_SWIFT_NAME(TaskRunners)
15+
@interface FlutterFMLTaskRunners : NSObject
16+
17+
@property(nonatomic, readonly) NSString* label;
18+
@property(nonatomic, readonly) FlutterFMLTaskRunner* platformTaskRunner;
19+
@property(nonatomic, readonly) FlutterFMLTaskRunner* rasterTaskRunner;
20+
@property(nonatomic, readonly) FlutterFMLTaskRunner* uiTaskRunner;
21+
@property(nonatomic, readonly) FlutterFMLTaskRunner* ioTaskRunner;
22+
23+
- (instancetype)initWithLabel:(NSString*)label
24+
platformTaskRunner:(FlutterFMLTaskRunner*)platformTaskRunner
25+
rasterTaskRunner:(FlutterFMLTaskRunner*)rasterTaskRunner
26+
uiTaskRunner:(FlutterFMLTaskRunner*)uiTaskRunner
27+
ioTaskRunner:(FlutterFMLTaskRunner*)ioTaskRunner;
28+
29+
@end
30+
31+
NS_ASSUME_NONNULL_END
32+
33+
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERFMLTASKRUNNERS_H_

0 commit comments

Comments
 (0)