From c2bf063f8146376cb9ddba4088160f112edac8be Mon Sep 17 00:00:00 2001 From: fuwa Date: Sat, 28 Dec 2019 13:05:31 +0800 Subject: [PATCH] use runtimeType to determine state type --- cyberwow/lib/main.dart | 45 ++++++++++------------- cyberwow/lib/state.dart | 57 +++++++----------------------- cyberwow/lib/widget.dart | 42 ++++++++++++++++++++++ cyberwow/lib/widget/blank.dart | 2 +- cyberwow/lib/widget/exiting.dart | 2 +- cyberwow/lib/widget/loading.dart | 2 +- cyberwow/lib/widget/resyncing.dart | 2 +- cyberwow/lib/widget/synced.dart | 2 +- cyberwow/lib/widget/syncing.dart | 2 +- 9 files changed, 79 insertions(+), 77 deletions(-) create mode 100644 cyberwow/lib/widget.dart diff --git a/cyberwow/lib/main.dart b/cyberwow/lib/main.dart index cc8d33e..ca0c3ee 100644 --- a/cyberwow/lib/main.dart +++ b/cyberwow/lib/main.dart @@ -32,12 +32,7 @@ import 'config.dart' as config; import 'logging.dart'; import 'controller/process/deploy.dart' as process; import 'controller/process/run.dart' as process; -import 'widget/loading.dart' as widget; -import 'widget/blank.dart' as widget; -import 'widget/syncing.dart' as widget; -import 'widget/synced.dart' as widget; -import 'widget/resyncing.dart' as widget; -import 'widget/exiting.dart' as widget; +import 'widget.dart' as widget; void main() { Logger.root.level = kReleaseMode ? Level.INFO : Level.FINE; @@ -128,7 +123,7 @@ class _CyberWOW_PageState extends State with WidgetsBindingObserv .runBinary(binName, input: inputStreamController.stream, shouldExit: _isExiting) .asBroadcastStream(); - HookedState _syncedNextState = await _syncingState.next(inputStreamController.sink, syncing); + AppState _syncedNextState = await _syncingState.next(inputStreamController.sink, syncing); var exited = false; @@ -143,19 +138,25 @@ class _CyberWOW_PageState extends State with WidgetsBindingObserv var validState = true; while (validState && !exited) { - await _getState().use - ( - (s) => validState = false, - (s) => validState = false, - (s) => validState = false, - (s) => s.next(), - (s) => s.next(), - (s) async { - await s.wait(); + AppState _state = _getState(); + switch (_state.runtimeType) { + case ExitingState: { + await (_state as ExitingState).wait(); log.finer('exit state wait done'); exited = true; } - ); + break; + + case SyncedState: + (_state as SyncedState).next(); + break; + + case ReSyncingState: + (_state as ReSyncingState).next(); + break; + + default: validState = false; + } } log.finer('state machine finished'); @@ -203,15 +204,7 @@ class _CyberWOW_PageState extends State with WidgetsBindingObserv return WillPopScope ( onWillPop: () => _exitApp(context), - child: _state.use - ( - (s) => widget.buildBlank(context, s), - (s) => widget.buildLoading(context, s), - (s) => widget.buildSyncing(context, s), - (s) => widget.buildSynced(context, s), - (s) => widget.buildReSyncing(context, s), - (s) => widget.buildExiting(context, s), - ), + child: widget.build(context, _state), ); } } diff --git a/cyberwow/lib/state.dart b/cyberwow/lib/state.dart index 1cf6894..a8695a7 100644 --- a/cyberwow/lib/state.dart +++ b/cyberwow/lib/state.dart @@ -40,39 +40,6 @@ import 'helper.dart'; import 'controller/rpc/rpcView.dart' as rpcView; import 'controller/rpc/rpc2View.dart' as rpc2View; -abstract class AppState { - T use - ( - T Function(BlankState) useBlankState, - T Function(LoadingState) useLoadingState, - T Function(SyncingState) useSyncingState, - T Function(SyncedState) useSyncedState, - T Function(ReSyncingState) useReSyncingState, - T Function(ExitingState) useExitingState, - ) - { - if (this is BlankState) { - return useBlankState(this); - } - if (this is LoadingState) { - return useLoadingState(this); - } - if (this is SyncingState) { - return useSyncingState(this); - } - if (this is SyncedState) { - return useSyncedState(this); - } - if (this is ReSyncingState) { - return useReSyncingState(this); - } - if (this is ExitingState) { - return useExitingState(this); - } - throw Exception('Invalid state'); - } -} - typedef SetStateFunc = void Function(AppState); typedef GetNotificationFunc = AppLifecycleState Function(); typedef IsExitingFunc = bool Function(); @@ -84,21 +51,21 @@ class AppHook { AppHook(this.setState, this.getNotification, this.isExiting); } -class HookedState extends AppState { +class AppState { final AppHook appHook; - HookedState(this.appHook); + AppState(this.appHook); syncState() { appHook.setState(this); } - HookedState moveState(HookedState _next) { + AppState moveState(AppState _next) { appHook.setState(_next); return _next; } } -class BlankState extends HookedState { +class BlankState extends AppState { BlankState(appHook) : super (appHook); Future next(String status) async { @@ -107,7 +74,7 @@ class BlankState extends HookedState { } } -class LoadingState extends HookedState { +class LoadingState extends AppState { final String banner; String status = ''; @@ -156,7 +123,7 @@ class LoadingState extends HookedState { } } -class SyncingState extends HookedState { +class SyncingState extends AppState { final Queue stdout = Queue.from(['']); bool synced = false; @@ -171,7 +138,7 @@ class SyncingState extends HookedState { syncState(); } - Future next + Future next ( StreamSink processInput, Stream processOutput ) async { @@ -233,7 +200,7 @@ class SyncingState extends HookedState { } } -class SyncedState extends HookedState { +class SyncedState extends AppState { final Queue stdout; final StreamSink processInput; final Stream processOutput; @@ -281,7 +248,7 @@ class SyncedState extends HookedState { this.pageIndex = value; } - Future next() async { + Future next() async { log.fine("Synced next"); Future logStdout() async { @@ -353,7 +320,7 @@ class SyncedState extends HookedState { } -class ReSyncingState extends HookedState { +class ReSyncingState extends AppState { final Queue stdout; final StreamSink processInput; final Stream processOutput; @@ -372,7 +339,7 @@ class ReSyncingState extends HookedState { syncState(); } - Future next() async { + Future next() async { log.fine("ReSyncing next"); Future printStdout() async { @@ -420,7 +387,7 @@ class ReSyncingState extends HookedState { } } -class ExitingState extends HookedState { +class ExitingState extends AppState { final Queue stdout; final Stream processOutput; diff --git a/cyberwow/lib/widget.dart b/cyberwow/lib/widget.dart new file mode 100644 index 0000000..89ac2dc --- /dev/null +++ b/cyberwow/lib/widget.dart @@ -0,0 +1,42 @@ +/* + +Copyright 2019 fuwa + +This file is part of CyberWOW. + +CyberWOW is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +CyberWOW is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with CyberWOW. If not, see . + +*/ + +import 'package:flutter/material.dart'; + +import 'state.dart'; +import 'widget/blank.dart' as blank; +import 'widget/loading.dart' as loading; +import 'widget/syncing.dart' as syncing; +import 'widget/synced.dart' as synced; +import 'widget/resyncing.dart' as resyncing; +import 'widget/exiting.dart' as exiting; + +Widget build(final BuildContext context, final AppState state) { + switch (state.runtimeType) { + case BlankState: return blank.build(context, state); + case LoadingState: return loading.build(context, state); + case SyncingState: return syncing.build(context, state); + case SyncedState: return synced.build(context, state); + case ReSyncingState: return resyncing.build(context, state); + case ExitingState: return exiting.build(context, state); + default: Placeholder(); + } +} diff --git a/cyberwow/lib/widget/blank.dart b/cyberwow/lib/widget/blank.dart index d2f13bf..847f2ff 100644 --- a/cyberwow/lib/widget/blank.dart +++ b/cyberwow/lib/widget/blank.dart @@ -24,7 +24,7 @@ import 'package:flutter/material.dart'; import '../state.dart'; import '../config.dart' as config; -Widget buildBlank(BuildContext context, BlankState state) { +Widget build(BuildContext context, BlankState state) { return Scaffold( body: Container ( diff --git a/cyberwow/lib/widget/exiting.dart b/cyberwow/lib/widget/exiting.dart index 45f6904..8703f27 100644 --- a/cyberwow/lib/widget/exiting.dart +++ b/cyberwow/lib/widget/exiting.dart @@ -24,7 +24,7 @@ import 'package:flutter/material.dart'; import '../state.dart'; import '../config.dart' as config; -Widget buildExiting(BuildContext context, ExitingState state) { +Widget build(BuildContext context, ExitingState state) { return Scaffold ( // appBar: AppBar diff --git a/cyberwow/lib/widget/loading.dart b/cyberwow/lib/widget/loading.dart index 4a4ec1a..89be27c 100644 --- a/cyberwow/lib/widget/loading.dart +++ b/cyberwow/lib/widget/loading.dart @@ -24,7 +24,7 @@ import 'package:flutter/material.dart'; import '../state.dart'; import '../config.dart' as config; -Widget buildLoading(BuildContext context, LoadingState state) { +Widget build(BuildContext context, LoadingState state) { return Scaffold( // appBar: AppBar( // // title: Text(widget.title), diff --git a/cyberwow/lib/widget/resyncing.dart b/cyberwow/lib/widget/resyncing.dart index 1e1eb46..dc6f20a 100644 --- a/cyberwow/lib/widget/resyncing.dart +++ b/cyberwow/lib/widget/resyncing.dart @@ -24,7 +24,7 @@ import 'package:flutter/material.dart'; import '../state.dart'; import '../config.dart' as config; -Widget buildReSyncing(BuildContext context, ReSyncingState state) { +Widget build(BuildContext context, ReSyncingState state) { return Scaffold ( // appBar: AppBar diff --git a/cyberwow/lib/widget/synced.dart b/cyberwow/lib/widget/synced.dart index a6ba5e7..0334cd3 100644 --- a/cyberwow/lib/widget/synced.dart +++ b/cyberwow/lib/widget/synced.dart @@ -320,7 +320,7 @@ Widget pageView (BuildContext context, SyncedState state) { ); } -Widget buildSynced(BuildContext context, SyncedState state) { +Widget build(BuildContext context, SyncedState state) { return Scaffold ( body: pageView(context, state) diff --git a/cyberwow/lib/widget/syncing.dart b/cyberwow/lib/widget/syncing.dart index f1fb3fa..4e50b2c 100644 --- a/cyberwow/lib/widget/syncing.dart +++ b/cyberwow/lib/widget/syncing.dart @@ -24,7 +24,7 @@ import 'package:flutter/material.dart'; import '../state.dart'; import '../config.dart' as config; -Widget buildSyncing(BuildContext context, SyncingState state) { +Widget build(BuildContext context, SyncingState state) { return Scaffold ( // appBar: AppBar