startup.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import 'dart:io';
  2. import 'package:appflowy_backend/appflowy_backend.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:get_it/get_it.dart';
  6. import '../workspace/application/settings/settings_location_cubit.dart';
  7. import 'deps_resolver.dart';
  8. import 'launch_configuration.dart';
  9. import 'plugin/plugin.dart';
  10. import 'tasks/prelude.dart';
  11. // [[diagram: flowy startup flow]]
  12. // ┌──────────┐
  13. // │ FlowyApp │
  14. // └──────────┘
  15. // │ impl
  16. // ▼
  17. // ┌────────┐ 1.run ┌──────────┐
  18. // │ System │───┬───▶│EntryPoint│
  19. // └────────┘ │ └──────────┘ ┌─────────────────┐
  20. // │ ┌──▶ │ RustSDKInitTask │
  21. // │ ┌───────────┐ │ └─────────────────┘
  22. // └──▶ │AppLauncher│───┤
  23. // 2.launch └───────────┘ │ ┌─────────────┐ ┌──────────────────┐ ┌───────────────┐
  24. // └───▶│AppWidgetTask│────────▶│ApplicationWidget │─────▶│ SplashScreen │
  25. // └─────────────┘ └──────────────────┘ └───────────────┘
  26. //
  27. // 3.build MaterialApp
  28. final getIt = GetIt.instance;
  29. abstract class EntryPoint {
  30. Widget create(LaunchConfiguration config);
  31. }
  32. class FlowyRunner {
  33. static Future<void> run(
  34. EntryPoint f, {
  35. LaunchConfiguration config =
  36. const LaunchConfiguration(autoRegistrationSupported: false),
  37. }) async {
  38. // Clear all the states in case of rebuilding.
  39. await getIt.reset();
  40. // Specify the env
  41. final env = integrationEnv();
  42. initGetIt(getIt, env, f, config);
  43. final directory = getIt<SettingsLocationCubit>()
  44. .fetchLocation()
  45. .then((value) => Directory(value));
  46. // add task
  47. getIt<AppLauncher>().addTask(InitRustSDKTask(directory: directory));
  48. getIt<AppLauncher>().addTask(PluginLoadTask());
  49. if (!env.isTest()) {
  50. getIt<AppLauncher>().addTask(InitAppWidgetTask());
  51. getIt<AppLauncher>().addTask(InitPlatformServiceTask());
  52. }
  53. // execute the tasks
  54. await getIt<AppLauncher>().launch();
  55. }
  56. }
  57. Future<void> initGetIt(
  58. GetIt getIt,
  59. IntegrationMode env,
  60. EntryPoint f,
  61. LaunchConfiguration config,
  62. ) async {
  63. getIt.registerFactory<EntryPoint>(() => f);
  64. getIt.registerLazySingleton<FlowySDK>(() {
  65. return FlowySDK();
  66. });
  67. getIt.registerLazySingleton<AppLauncher>(
  68. () => AppLauncher(
  69. context: LaunchContext(
  70. getIt,
  71. env,
  72. config,
  73. ),
  74. ),
  75. );
  76. getIt.registerSingleton<PluginSandbox>(PluginSandbox());
  77. await DependencyResolver.resolve(getIt);
  78. }
  79. class LaunchContext {
  80. GetIt getIt;
  81. IntegrationMode env;
  82. LaunchConfiguration config;
  83. LaunchContext(this.getIt, this.env, this.config);
  84. }
  85. enum LaunchTaskType {
  86. dataProcessing,
  87. appLauncher,
  88. }
  89. /// The interface of an app launch task, which will trigger
  90. /// some nonresident indispensable task in app launching task.
  91. abstract class LaunchTask {
  92. LaunchTaskType get type => LaunchTaskType.dataProcessing;
  93. Future<void> initialize(LaunchContext context);
  94. }
  95. class AppLauncher {
  96. List<LaunchTask> tasks;
  97. final LaunchContext context;
  98. AppLauncher({required this.context}) : tasks = List.from([]);
  99. void addTask(LaunchTask task) {
  100. tasks.add(task);
  101. }
  102. Future<void> launch() async {
  103. for (var task in tasks) {
  104. await task.initialize(context);
  105. }
  106. }
  107. }
  108. enum IntegrationMode {
  109. develop,
  110. release,
  111. test,
  112. }
  113. extension IntegrationEnvExt on IntegrationMode {
  114. bool isTest() {
  115. return this == IntegrationMode.test;
  116. }
  117. }
  118. IntegrationMode integrationEnv() {
  119. if (Platform.environment.containsKey('FLUTTER_TEST')) {
  120. return IntegrationMode.test;
  121. }
  122. if (kReleaseMode) {
  123. return IntegrationMode.release;
  124. }
  125. return IntegrationMode.develop;
  126. }