Skip to content
Snippets Groups Projects
Commit d755815e authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Normalize Activity application architecture

parent 77607ceb
No related branches found
No related tags found
1 merge request!27Resolve "Normalize Activity application architecture"
Pipeline #6678 passed
Showing
with 598 additions and 51 deletions
{
"app_name": "Solitaire",
"page_home": "Home",
"page_game": "Game",
"settings_title": "Settings",
"settings_label_theme": "Theme mode",
......
{
"app_name": "Solitaire",
"page_home": "Accueil",
"page_game": "Jeu",
"settings_title": "Réglages",
"settings_label_theme": "Thème de couleurs",
......
Normalize Activity application architecture.
Harmonisation des applications en Activity.
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/ui/screens/page_about.dart';
import 'package:solitaire/ui/screens/page_game.dart';
import 'package:solitaire/ui/screens/page_settings.dart';
import 'package:solitaire/common/ui/pages/game.dart';
import 'package:solitaire/common/ui/pages/parameters.dart';
class MenuItem {
class ActivityPageItem {
final String code;
final Icon icon;
final Widget page;
const MenuItem({
const ActivityPageItem({
required this.code,
required this.icon,
required this.page,
});
}
class Menu {
static const indexGame = 0;
static const menuItemGame = MenuItem(
icon: Icon(UniconsLine.home),
page: PageGame(),
);
class ActivityPage {
static const bool displayBottomNavBar = false;
static const indexSettings = 1;
static const menuItemSettings = MenuItem(
icon: Icon(UniconsLine.setting),
page: PageSettings(),
static const indexHome = 0;
static const pageHome = ActivityPageItem(
code: 'page_home',
icon: Icon(UniconsLine.home),
page: PageParameters(),
);
static const indexAbout = 2;
static const menuItemAbout = MenuItem(
icon: Icon(UniconsLine.info_circle),
page: PageAbout(),
static const indexGame = 1;
static const pageGame = ActivityPageItem(
code: 'page_game',
icon: Icon(UniconsLine.star),
page: PageGame(),
);
static Map<int, MenuItem> items = {
indexGame: menuItemGame,
indexSettings: menuItemSettings,
indexAbout: menuItemAbout,
static const Map<int, ActivityPageItem> items = {
indexHome: pageHome,
indexGame: pageGame,
};
static int defaultPageIndex = indexHome;
static bool isIndexAllowed(int pageIndex) {
return items.keys.contains(pageIndex);
}
static Widget getPageWidget(int pageIndex) {
return items[pageIndex]?.page ?? menuItemGame.page;
static Widget getWidget(int pageIndex) {
return items[pageIndex]?.page ?? pageHome.page;
}
static int itemsCount = Menu.items.length;
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/common/ui/screens/about.dart';
import 'package:solitaire/common/ui/screens/activity.dart';
import 'package:solitaire/common/ui/screens/settings.dart';
class ScreenItem {
final String code;
final Icon icon;
final Widget screen;
const ScreenItem({
required this.code,
required this.icon,
required this.screen,
});
}
class Screen {
static const indexActivity = 0;
static const screenActivity = ScreenItem(
code: 'screen_activity',
icon: Icon(UniconsLine.home),
screen: ScreenActivity(),
);
static const indexSettings = 1;
static const screenSettings = ScreenItem(
code: 'screen_settings',
icon: Icon(UniconsLine.setting),
screen: ScreenSettings(),
);
static const indexAbout = 2;
static const screenAbout = ScreenItem(
code: 'screen_about',
icon: Icon(UniconsLine.info_circle),
screen: ScreenAbout(),
);
static Map<int, ScreenItem> items = {
indexActivity: screenActivity,
indexSettings: screenSettings,
indexAbout: screenAbout,
};
static bool isIndexAllowed(int screenIndex) {
return items.keys.contains(screenIndex);
}
static Widget getWidget(int screenIndex) {
return items[screenIndex]?.screen ?? screenActivity.screen;
}
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/config/menu.dart';
import 'package:solitaire/common/config/activity_page.dart';
class NavCubit extends HydratedCubit<int> {
NavCubit() : super(0);
class NavCubitPage extends HydratedCubit<int> {
NavCubitPage() : super(0);
void updateIndex(int index) {
if (Menu.isIndexAllowed(index)) {
if (ActivityPage.isIndexAllowed(index)) {
emit(index);
} else {
goToGamePage();
emit(ActivityPage.indexHome);
}
}
void goToGamePage() {
emit(Menu.indexGame);
void goToPageHome() {
updateIndex(ActivityPage.indexHome);
}
void goToSettingsPage() {
emit(Menu.indexSettings);
}
void goToAboutPage() {
emit(Menu.indexAbout);
void goToPageGame() {
updateIndex(ActivityPage.indexGame);
}
@override
int fromJson(Map<String, dynamic> json) {
return Menu.indexGame;
return ActivityPage.indexHome;
}
@override
Map<String, dynamic>? toJson(int state) {
return <String, int>{'pageIndex': state};
return <String, int>{'index': state};
}
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/common/config/screen.dart';
class NavCubitScreen extends HydratedCubit<int> {
NavCubitScreen() : super(0);
void updateIndex(int index) {
if (Screen.isIndexAllowed(index)) {
emit(index);
} else {
goToScreenActivity();
}
}
void goToScreenActivity() {
emit(Screen.indexActivity);
}
void goToScreenSettings() {
emit(Screen.indexSettings);
}
void goToScreenAbout() {
emit(Screen.indexAbout);
}
@override
int fromJson(Map<String, dynamic> json) {
return Screen.indexActivity;
}
@override
Map<String, dynamic>? toJson(int state) {
return <String, int>{'index': state};
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/common/config/activity_page.dart';
import 'package:solitaire/common/cubit/nav/nav_cubit_pages.dart';
class BottomNavBar extends StatelessWidget {
const BottomNavBar({super.key});
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.only(top: 1, right: 4, left: 4),
elevation: 4,
shadowColor: Theme.of(context).colorScheme.shadow,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: BlocBuilder<NavCubitPage, int>(builder: (BuildContext context, int state) {
final List<BottomNavigationBarItem> items = [];
ActivityPage.items.forEach((int pageIndex, ActivityPageItem item) {
items.add(BottomNavigationBarItem(
icon: item.icon,
label: tr(item.code),
));
});
return BottomNavigationBar(
currentIndex: state,
onTap: (int index) => BlocProvider.of<NavCubitPage>(context).updateIndex(index),
type: BottomNavigationBarType.fixed,
elevation: 0,
backgroundColor: Colors.transparent,
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
items: items,
);
}),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/config/menu.dart';
import 'package:solitaire/cubit/game_cubit.dart';
import 'package:solitaire/cubit/nav_cubit.dart';
import 'package:solitaire/models/game/game.dart';
import 'package:solitaire/common/config/screen.dart';
import 'package:solitaire/common/cubit/nav/nav_cubit_pages.dart';
import 'package:solitaire/common/cubit/nav/nav_cubit_screens.dart';
import 'package:solitaire/cubit/activity/activity_cubit.dart';
import 'package:solitaire/models/activity/activity.dart';
class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
const GlobalAppBar({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
return BlocBuilder<NavCubit, int>(
return BlocBuilder<ActivityCubit, ActivityState>(
builder: (BuildContext context, ActivityState activityState) {
return BlocBuilder<NavCubitScreen, int>(
builder: (BuildContext context, int pageIndex) {
final Game currentGame = gameState.currentGame;
final Activity currentActivity = activityState.currentActivity;
final List<Widget> menuActions = [];
if (currentGame.isRunning && !currentGame.isFinished) {
if (currentActivity.isRunning && !currentActivity.isFinished) {
menuActions.add(StyledButton(
color: Colors.red,
onPressed: () {},
onLongPress: () {
BlocProvider.of<GameCubit>(context).quitGame();
BlocProvider.of<ActivityCubit>(context).quitActivity();
BlocProvider.of<NavCubitPage>(context).goToPageHome();
},
child: const Image(
image: AssetImage('assets/ui/button_back.png'),
......@@ -32,38 +35,38 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
),
));
} else {
if (pageIndex == Menu.indexGame) {
if (pageIndex == Screen.indexActivity) {
// go to Settings page
menuActions.add(ElevatedButton(
onPressed: () {
BlocProvider.of<NavCubit>(context).goToSettingsPage();
BlocProvider.of<NavCubitScreen>(context).goToScreenSettings();
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
),
child: Menu.menuItemSettings.icon,
child: Screen.screenSettings.icon,
));
// go to About page
menuActions.add(ElevatedButton(
onPressed: () {
BlocProvider.of<NavCubit>(context).goToAboutPage();
BlocProvider.of<NavCubitScreen>(context).goToScreenAbout();
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
),
child: Menu.menuItemAbout.icon,
child: Screen.screenAbout.icon,
));
} else {
// back to Home page
menuActions.add(ElevatedButton(
onPressed: () {
BlocProvider.of<NavCubit>(context).goToGamePage();
BlocProvider.of<NavCubitScreen>(context).goToScreenActivity();
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
),
child: Menu.menuItemGame.icon,
child: Screen.screenActivity.icon,
));
}
}
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/cubit/game_cubit.dart';
import 'package:solitaire/models/game/game.dart';
import 'package:solitaire/cubit/activity/activity_cubit.dart';
import 'package:solitaire/models/activity/activity.dart';
import 'package:solitaire/ui/game/game_end.dart';
import 'package:solitaire/ui/game/game_top.dart';
import 'package:solitaire/ui/widgets/game/game_board.dart';
class GameLayout extends StatelessWidget {
const GameLayout({super.key});
class PageGame extends StatelessWidget {
const PageGame({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<GameCubit, GameState>(
builder: (BuildContext context, GameState gameState) {
final Game currentGame = gameState.currentGame;
return BlocBuilder<ActivityCubit, ActivityState>(
builder: (BuildContext context, ActivityState activityState) {
final Activity currentActivity = activityState.currentActivity;
return Container(
alignment: AlignmentDirectional.topCenter,
......@@ -28,7 +28,7 @@ class GameLayout extends StatelessWidget {
const GameBoardWidget(),
const SizedBox(height: 8),
const Expanded(child: SizedBox.shrink()),
currentGame.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
currentActivity.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
],
),
);
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/config/default_game_settings.dart';
import 'package:solitaire/common/ui/parameters/parameter_widget.dart';
import 'package:solitaire/config/default_activity_settings.dart';
import 'package:solitaire/config/default_global_settings.dart';
import 'package:solitaire/cubit/settings_game_cubit.dart';
import 'package:solitaire/cubit/settings_global_cubit.dart';
import 'package:solitaire/ui/parameters/parameter_widget.dart';
import 'package:solitaire/cubit/activity/activity_cubit.dart';
import 'package:solitaire/cubit/settings/settings_activity_cubit.dart';
import 'package:solitaire/cubit/settings/settings_global_cubit.dart';
import 'package:solitaire/models/activity/activity.dart';
import 'package:solitaire/ui/widgets/actions/button_delete_saved_game.dart';
import 'package:solitaire/ui/widgets/actions/button_game_start_new.dart';
import 'package:solitaire/ui/widgets/actions/button_resume_saved_game.dart';
class ParametersLayout extends StatelessWidget {
const ParametersLayout({super.key, required this.canResume});
final bool canResume;
class PageParameters extends StatelessWidget {
const PageParameters({super.key});
final double separatorHeight = 8.0;
@override
Widget build(BuildContext context) {
final List<Widget> lines = [];
// Game settings
for (String code in DefaultGameSettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
code: code,
isGlobal: false,
),
));
lines.add(SizedBox(height: separatorHeight));
}
lines.add(Expanded(
child: SizedBox(height: separatorHeight),
));
if (canResume == false) {
// Start new game
lines.add(
const AspectRatio(
aspectRatio: 3,
child: StartNewGameButton(),
),
);
} else {
// Resume game
lines.add(const AspectRatio(
aspectRatio: 3,
child: ResumeSavedGameButton(),
));
// Delete saved game
lines.add(SizedBox.square(
dimension: MediaQuery.of(context).size.width / 5,
child: const DeleteSavedGameButton(),
));
}
lines.add(SizedBox(height: separatorHeight));
// Global settings
for (String code in DefaultGlobalSettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
code: code,
isGlobal: true,
),
));
lines.add(SizedBox(height: separatorHeight));
}
return Column(
children: lines,
return BlocBuilder<ActivityCubit, ActivityState>(
builder: (BuildContext context, ActivityState activityState) {
final Activity currentActivity = activityState.currentActivity;
final List<Widget> lines = [];
// Game settings
for (String code in DefaultActivitySettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
code: code,
isGlobal: false,
),
));
lines.add(SizedBox(height: separatorHeight));
}
lines.add(Expanded(
child: SizedBox(height: separatorHeight),
));
if (currentActivity.canBeResumed == false) {
// Start new game
lines.add(
const AspectRatio(
aspectRatio: 3,
child: StartNewGameButton(),
),
);
} else {
// Resume game
lines.add(const AspectRatio(
aspectRatio: 3,
child: ResumeSavedGameButton(),
));
// Delete saved game
lines.add(SizedBox.square(
dimension: MediaQuery.of(context).size.width / 5,
child: const DeleteSavedGameButton(),
));
}
lines.add(SizedBox(height: separatorHeight));
// Global settings
for (String code in DefaultGlobalSettings.availableParameters) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
code: code,
isGlobal: true,
),
));
lines.add(SizedBox(height: separatorHeight));
}
return Column(
children: lines,
);
},
);
}
......@@ -87,25 +94,25 @@ class ParametersLayout extends StatelessWidget {
final List<String> availableValues = isGlobal
? DefaultGlobalSettings.getAvailableValues(code)
: DefaultGameSettings.getAvailableValues(code);
: DefaultActivitySettings.getAvailableValues(code);
if (availableValues.length <= 1) {
return [];
}
for (String value in availableValues) {
final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
builder: (BuildContext context, GameSettingsState gameSettingsState) {
final Widget parameterButton = BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
final GameSettingsCubit gameSettingsCubit =
BlocProvider.of<GameSettingsCubit>(context);
final ActivitySettingsCubit activitySettingsCubit =
BlocProvider.of<ActivitySettingsCubit>(context);
final GlobalSettingsCubit globalSettingsCubit =
BlocProvider.of<GlobalSettingsCubit>(context);
final String currentValue = isGlobal
? globalSettingsCubit.getParameterValue(code)
: gameSettingsCubit.getParameterValue(code);
: activitySettingsCubit.getParameterValue(code);
final bool isSelected = (value == currentValue);
......@@ -119,12 +126,12 @@ class ParametersLayout extends StatelessWidget {
value: value,
isSelected: isSelected,
size: itemWidth,
gameSettings: gameSettingsState.settings,
activitySettings: activitySettingsState.settings,
globalSettings: globalSettingsState.settings,
onPressed: () {
isGlobal
? globalSettingsCubit.setParameterValue(code, value)
: gameSettingsCubit.setParameterValue(code, value);
: activitySettingsCubit.setParameterValue(code, value);
},
),
);
......
......@@ -3,25 +3,26 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/config/default_game_settings.dart';
import 'package:solitaire/data/game_data.dart';
import 'package:solitaire/models/game/board.dart';
import 'package:solitaire/models/game/cell.dart';
import 'package:solitaire/models/game/cell_location.dart';
import 'package:solitaire/models/settings/settings_game.dart';
import 'package:solitaire/config/default_activity_settings.dart';
import 'package:solitaire/models/settings/settings_activity.dart';
import 'package:solitaire/models/settings/settings_global.dart';
import 'package:solitaire/data/game_data.dart';
import 'package:solitaire/models/activity/board.dart';
import 'package:solitaire/models/activity/cell.dart';
import 'package:solitaire/models/activity/cell_location.dart';
class ParameterPainter extends CustomPainter {
const ParameterPainter({
required this.code,
required this.value,
required this.gameSettings,
required this.activitySettings,
required this.globalSettings,
});
final String code;
final String value;
final GameSettings gameSettings;
final ActivitySettings activitySettings;
final GlobalSettings globalSettings;
@override
......@@ -31,7 +32,7 @@ class ParameterPainter extends CustomPainter {
// content
switch (code) {
case DefaultGameSettings.parameterCodeLayout:
case DefaultActivitySettings.parameterCodeLayout:
paintLayoutParameterItem(canvas, canvasSize);
break;
default:
......@@ -85,16 +86,16 @@ class ParameterPainter extends CustomPainter {
Color gridBackgroundColor = Colors.grey;
switch (value) {
case DefaultGameSettings.layoutValueFrench:
case DefaultActivitySettings.layoutValueFrench:
gridBackgroundColor = Colors.green;
break;
case DefaultGameSettings.layoutValueGerman:
case DefaultActivitySettings.layoutValueGerman:
gridBackgroundColor = Colors.orange;
break;
case DefaultGameSettings.layoutValueEnglish:
case DefaultActivitySettings.layoutValueEnglish:
gridBackgroundColor = Colors.red;
break;
case DefaultGameSettings.layoutValueDiamond:
case DefaultActivitySettings.layoutValueDiamond:
gridBackgroundColor = Colors.purple;
break;
default:
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/config/default_game_settings.dart';
import 'package:solitaire/common/ui/parameters/parameter_painter.dart';
import 'package:solitaire/config/default_activity_settings.dart';
import 'package:solitaire/config/default_global_settings.dart';
import 'package:solitaire/models/settings/settings_game.dart';
import 'package:solitaire/models/settings/settings_activity.dart';
import 'package:solitaire/models/settings/settings_global.dart';
import 'package:solitaire/ui/parameters/parameter_painter.dart';
class ParameterWidget extends StatelessWidget {
const ParameterWidget({
......@@ -14,7 +15,7 @@ class ParameterWidget extends StatelessWidget {
required this.value,
required this.isSelected,
required this.size,
required this.gameSettings,
required this.activitySettings,
required this.globalSettings,
required this.onPressed,
});
......@@ -23,7 +24,7 @@ class ParameterWidget extends StatelessWidget {
final String value;
final bool isSelected;
final double size;
final GameSettings gameSettings;
final ActivitySettings activitySettings;
final GlobalSettings globalSettings;
final VoidCallback onPressed;
......@@ -37,7 +38,7 @@ class ParameterWidget extends StatelessWidget {
Widget content = const SizedBox.shrink();
switch (code) {
case DefaultGameSettings.parameterCodeLayout:
case DefaultActivitySettings.parameterCodeLayout:
content = getLayoutParameterItem();
break;
case DefaultGlobalSettings.parameterCodeSkin:
......@@ -84,7 +85,7 @@ class ParameterWidget extends StatelessWidget {
painter: ParameterPainter(
code: code,
value: value,
gameSettings: gameSettings,
activitySettings: activitySettings,
globalSettings: globalSettings,
),
isComplex: true,
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class PageAbout extends StatelessWidget {
const PageAbout({super.key});
class ScreenAbout extends StatelessWidget {
const ScreenAbout({super.key});
@override
Widget build(BuildContext context) {
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/common/config/activity_page.dart';
import 'package:solitaire/common/cubit/nav/nav_cubit_pages.dart';
class ScreenActivity extends StatelessWidget {
const ScreenActivity({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<NavCubitPage, int>(
builder: (BuildContext context, int pageIndex) {
return ActivityPage.getWidget(pageIndex);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class PageSettings extends StatelessWidget {
const PageSettings({super.key});
class ScreenSettings extends StatelessWidget {
const ScreenSettings({super.key});
@override
Widget build(BuildContext context) {
......
class ApplicationConfig {
static const String appTitle = 'Solitaire';
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class DefaultGameSettings {
class DefaultActivitySettings {
// available game parameters codes
static const String parameterCodeLayout = 'layout';
static const List<String> availableParameters = [
......@@ -25,7 +25,7 @@ class DefaultGameSettings {
static List<String> getAvailableValues(String parameterCode) {
switch (parameterCode) {
case parameterCodeLayout:
return DefaultGameSettings.allowedLayoutValues;
return DefaultActivitySettings.allowedLayoutValues;
}
printlog('Did not find any available value for game parameter "$parameterCode".');
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:solitaire/models/game/cell_location.dart';
import 'package:solitaire/models/game/game.dart';
import 'package:solitaire/models/settings/settings_game.dart';
import 'package:solitaire/models/activity/cell_location.dart';
import 'package:solitaire/models/activity/activity.dart';
import 'package:solitaire/models/settings/settings_activity.dart';
import 'package:solitaire/models/settings/settings_global.dart';
part 'game_state.dart';
part 'activity_state.dart';
class GameCubit extends HydratedCubit<GameState> {
GameCubit()
: super(GameState(
currentGame: Game.createEmpty(),
class ActivityCubit extends HydratedCubit<ActivityState> {
ActivityCubit()
: super(ActivityState(
currentActivity: Activity.createEmpty(),
));
void updateState(Game game) {
emit(GameState(
currentGame: game,
void updateState(Activity activity) {
emit(ActivityState(
currentActivity: activity,
));
}
void refresh() {
final Game game = Game(
final Activity activity = Activity(
// Settings
gameSettings: state.currentGame.gameSettings,
globalSettings: state.currentGame.globalSettings,
activitySettings: state.currentActivity.activitySettings,
globalSettings: state.currentActivity.globalSettings,
// State
isRunning: state.currentGame.isRunning,
isStarted: state.currentGame.isStarted,
isFinished: state.currentGame.isFinished,
animationInProgress: state.currentGame.animationInProgress,
isRunning: state.currentActivity.isRunning,
isStarted: state.currentActivity.isStarted,
isFinished: state.currentActivity.isFinished,
animationInProgress: state.currentActivity.animationInProgress,
// Base data
board: state.currentGame.board,
board: state.currentActivity.board,
// Game data
movesCount: state.currentGame.movesCount,
remainingPegsCount: state.currentGame.remainingPegsCount,
allowedMovesCount: state.currentGame.allowedMovesCount,
movesCount: state.currentActivity.movesCount,
remainingPegsCount: state.currentActivity.remainingPegsCount,
allowedMovesCount: state.currentActivity.allowedMovesCount,
);
// game.dump();
updateState(game);
updateState(activity);
}
void startNewGame({
required GameSettings gameSettings,
void startNewActivity({
required ActivitySettings activitySettings,
required GlobalSettings globalSettings,
}) {
final Game newGame = Game.createNew(
final Activity newActivity = Activity.createNew(
// Settings
gameSettings: gameSettings,
activitySettings: activitySettings,
globalSettings: globalSettings,
);
newGame.dump();
newActivity.dump();
updateState(newGame);
updateState(newActivity);
updateRemainingPegsCount(newGame.countRemainingPegs());
updateAllowedMovesCount(newGame.countAllowedMoves());
updateRemainingPegsCount(newActivity.countRemainingPegs());
updateAllowedMovesCount(newActivity.countAllowedMoves());
refresh();
}
void quitGame() {
state.currentGame.isRunning = false;
void quitActivity() {
state.currentActivity.isRunning = false;
refresh();
}
void resumeSavedGame() {
state.currentGame.isRunning = true;
void resumeSavedActivity() {
state.currentActivity.isRunning = true;
refresh();
}
void deleteSavedGame() {
state.currentGame.isRunning = false;
state.currentGame.isFinished = true;
void deleteSavedActivity() {
state.currentActivity.isRunning = false;
state.currentActivity.isFinished = true;
refresh();
}
void updatePegValue(CellLocation location, bool hasPeg) {
state.currentGame.board.cells[location.row][location.col].hasPeg = hasPeg;
state.currentActivity.board.cells[location.row][location.col].hasPeg = hasPeg;
refresh();
}
void incrementMovesCount() {
state.currentGame.isStarted = true;
state.currentGame.movesCount++;
state.currentActivity.isStarted = true;
state.currentActivity.movesCount++;
refresh();
}
void updateRemainingPegsCount(int count) {
state.currentGame.remainingPegsCount = count;
state.currentActivity.remainingPegsCount = count;
refresh();
}
void updateAllowedMovesCount(int count) {
state.currentGame.allowedMovesCount = count;
state.currentActivity.allowedMovesCount = count;
if (count == 0) {
state.currentGame.isFinished = true;
state.currentActivity.isFinished = true;
}
refresh();
}
void move({
required Game currentGame,
required Activity currentActivity,
required List<int> source,
required List<int> target,
}) {
......@@ -122,23 +122,23 @@ class GameCubit extends HydratedCubit<GameState> {
updatePegValue(CellLocation.go(middleRow, middleCol), false);
incrementMovesCount();
updateRemainingPegsCount(currentGame.countRemainingPegs());
updateAllowedMovesCount(currentGame.countAllowedMoves());
updateRemainingPegsCount(currentActivity.countRemainingPegs());
updateAllowedMovesCount(currentActivity.countAllowedMoves());
}
@override
GameState? fromJson(Map<String, dynamic> json) {
final Game currentGame = json['currentGame'] as Game;
ActivityState? fromJson(Map<String, dynamic> json) {
final Activity currentActivity = json['currentActivity'] as Activity;
return GameState(
currentGame: currentGame,
return ActivityState(
currentActivity: currentActivity,
);
}
@override
Map<String, dynamic>? toJson(GameState state) {
Map<String, dynamic>? toJson(ActivityState state) {
return <String, dynamic>{
'currentGame': state.currentGame.toJson(),
'currentActivity': state.currentActivity.toJson(),
};
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment