ce4dd8d61d
- Introduced unit tests for the Wolf3dGuiApp to ensure proper directory configuration and audio management. - Refactored the GameDataPickerManager to streamline directory and file selection processes. - Removed obsolete GameDataPickerManager and Wolf3dAppManager classes to simplify the architecture. - Enhanced the Wolf3dFlutterEngine to improve game version handling during save loading. - Updated existing tests to reflect changes in the game data management structure. - Removed unnecessary dependencies and cleaned up the codebase for better maintainability. Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
157 lines
4.0 KiB
Dart
157 lines
4.0 KiB
Dart
library;
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:wolf_3d_flutter/wolf_3d_flutter.dart';
|
|
|
|
import 'game_data_picker_manager.dart';
|
|
import 'no_game_data_screen.dart';
|
|
|
|
/// GUI-host application shell that owns setup/import UX.
|
|
class Wolf3dGuiApp extends StatefulWidget {
|
|
/// Creates the GUI host shell for a prepared engine facade.
|
|
const Wolf3dGuiApp({
|
|
super.key,
|
|
required this.engine,
|
|
this.pickerManager,
|
|
});
|
|
|
|
/// Shared initialized facade that owns game data, input, and audio services.
|
|
final Wolf3dFlutterEngine engine;
|
|
|
|
/// Optional injected picker manager used by tests.
|
|
final GameDataPickerManager? pickerManager;
|
|
|
|
@override
|
|
State<Wolf3dGuiApp> createState() => _Wolf3dGuiAppState();
|
|
}
|
|
|
|
class _Wolf3dGuiAppState extends State<Wolf3dGuiApp>
|
|
with WidgetsBindingObserver {
|
|
late final GameDataPickerManager _pickerManager;
|
|
Future<void>? _shutdownFuture;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_pickerManager =
|
|
widget.pickerManager ?? GameDataPickerManager(engine: widget.engine);
|
|
WidgetsBinding.instance.addObserver(this);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
WidgetsBinding.instance.removeObserver(this);
|
|
unawaited(_ensureAudioShutdown());
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
if (state == AppLifecycleState.detached) {
|
|
unawaited(_ensureAudioShutdown());
|
|
}
|
|
}
|
|
|
|
Future<void> _ensureAudioShutdown() {
|
|
final Future<void>? existing = _shutdownFuture;
|
|
if (existing != null) {
|
|
return existing;
|
|
}
|
|
|
|
final Future<void> shutdown = widget.engine.shutdownAudio();
|
|
_shutdownFuture = shutdown;
|
|
return shutdown;
|
|
}
|
|
|
|
Future<void> _pickGameDataDirectory() {
|
|
return _runPickerAction(
|
|
() => _pickerManager.pickGameDataDirectory(
|
|
notifyChanged: () {
|
|
if (mounted) {
|
|
setState(() {});
|
|
}
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _pickGameDataFiles() {
|
|
return _runPickerAction(
|
|
() => _pickerManager.pickGameDataFiles(
|
|
notifyChanged: () {
|
|
if (mounted) {
|
|
setState(() {});
|
|
}
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _runPickerAction(Future<void> Function() action) async {
|
|
await action();
|
|
|
|
final GameDataVersionAnalysis? soleReadyVersion =
|
|
_pickerManager.scanResult?.soleReadyVersion;
|
|
if (soleReadyVersion == null ||
|
|
!mounted ||
|
|
widget.engine.availableGames.isNotEmpty) {
|
|
return;
|
|
}
|
|
|
|
if (_pickerManager.selectedReadyVersion != soleReadyVersion.version) {
|
|
setState(() {
|
|
_pickerManager.selectReadyVersion(soleReadyVersion.version);
|
|
});
|
|
}
|
|
|
|
await _useSelectedData();
|
|
}
|
|
|
|
Future<void> _useSelectedData() {
|
|
return _pickerManager.useSelectedData(
|
|
notifyChanged: () {
|
|
if (mounted) {
|
|
setState(() {});
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> _importSelectedData() {
|
|
return _pickerManager.importSelectedData(
|
|
notifyChanged: () {
|
|
if (mounted) {
|
|
setState(() {});
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return widget.engine.availableGames.isEmpty
|
|
? NoGameDataScreen(
|
|
configuredDataDirectory: widget.engine.configuredDataDirectory,
|
|
onPickGameDataDirectory: _pickGameDataDirectory,
|
|
onPickGameDataFiles: _pickGameDataFiles,
|
|
onUseSelectedData: _useSelectedData,
|
|
onImportSelectedData: _importSelectedData,
|
|
onSelectReadyVersion: (version) {
|
|
if (version == null) {
|
|
return;
|
|
}
|
|
setState(() {
|
|
_pickerManager.selectReadyVersion(version);
|
|
});
|
|
},
|
|
isLoadingGameData: _pickerManager.isLoadingGameData,
|
|
pickerError: _pickerManager.pickerError,
|
|
scanResult: _pickerManager.scanResult,
|
|
selectedReadyVersion: _pickerManager.selectedReadyVersion,
|
|
)
|
|
: GameScreen(wolf3d: widget.engine);
|
|
}
|
|
}
|