startup.dart 4.0 KB

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