startup.dart 3.9 KB

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