import 'package:dart_jts/dart_jts.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge.dart'; import 'package:get/get.dart'; import 'package:grpc/grpc.dart'; import 'package:trackoffical_app/exception/exception.dart'; import 'package:trackoffical_app/logger.dart'; import 'package:trackoffical_app/route.dart'; import 'package:trackoffical_app/service/game/game_manager_service.dart'; import 'package:trackoffical_app/service/mock.dart'; import 'package:trackoffical_app/styles/theme.dart'; import 'package:trackoffical_app/view/ingame/game_guardian/guardian_watch_game_view.dart'; import '../../service/game/game.dart'; import 'in_game_view.dart'; class InGameLoadingController extends GetxController { double get loadProgress => GameService.to.loadProgress; Worker? worker; @override void onReady() { super.onReady(); GameService.to.gameLoad().then( (value) => Get.offAll(() => const InGameView(), binding: InGameView.bindings()), onError: (e) { error('加载失败:', e); var msg = e.toString(); if (e is FfiException) { GameService.to.gameGiveUp(); msg = '地图包错误:${e.message}'; } Get.dialog(AlertDialog( icon: const Icon(Icons.error, color: Colors.red), title: const Text('加载失败!'), content: Text(msg), actions: [ FilledButton( onPressed: () { Get.offAllNamed(RouteName.home); }, child: const Text('确定')) ], )); }); } void onBack() {} } class GuardianLoadingController extends InGameLoadingController { @override void onReady() { final underGuardianId = Get.arguments; if (underGuardianId is! int) { throw RuntimeException('Argument not int: ${Get.arguments}'); } GameManagerService.to.guardianStart(underGuardianId).then((value) { Get.off(() => const GuardianWatchGameView(), binding: GuardianWatchGameView.bindings(), arguments: underGuardianId); }, onError: (e) { if (e is FutureCancel) { return; } error('加载失败:', e); var msg = e.toString(); if (e is FfiException) { msg = '地图包错误:${e.message}'; } if (e is GrpcError) { msg = '${e.message}'; } Get.dialog(AlertDialog( icon: const Icon(Icons.error, color: Colors.red), title: const Text('加载失败!'), content: Text(msg), actions: [ FilledButton( onPressed: () { Get.offAllNamed(RouteName.home); }, child: const Text('确定')) ], )); }); 100.milliseconds.delay().then((value){ final instance = GameManagerService.to.instance; if(instance!=null && !isClosed){ _loadProgress.bindStream(instance.loadProgress.stream); } }); } final _loadProgress = 0.0.obs; @override void onClose() { super.onClose(); _loadProgress.close(); } @override double get loadProgress => _loadProgress.value; @override void onBack() { GameManagerService.to.instanceStop(); } } class InGameLoadingView extends GetView { const InGameLoadingView({super.key}); static Bindings bindingsToGame() { return BindingsBuilder(() { Get.lazyPut(() => InGameLoadingController()); }); } static Bindings bindingsToGuardian() { return BindingsBuilder(() { Get.lazyPut(() => GuardianLoadingController()); }); } static void toGuardian(int id) { Get.to(() => const InGameLoadingView(), binding: bindingsToGuardian(), arguments: id); } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { controller.onBack(); return true; }, child: Scaffold( body: Center( child: Column(mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text('载入中,请稍后', style: context.textTheme.titleLarge), Image.asset('assets/images/loading.gif', height: 48), ]), const SizedBox(height: 12), SizedBox( height: 26, width: 220, child: Obx( () => LinearProgressIndicator(value: controller.loadProgress)), ) ])))); } } class InGameLoadingControllerMock extends InGameLoadingController { @override void onInit() { super.onInit(); debug('onInit'); } } void main() async { Mock.initServices(); Get.put(GameService()); var c = InGameLoadingControllerMock(); Get.put(c); runApp( GetMaterialApp(theme: appThemeData(), home: const InGameLoadingView())); }