From 569a3386a8ba078c46b930a7677ee32ce8af8f45 Mon Sep 17 00:00:00 2001 From: Hans Kokx Date: Mon, 23 Mar 2026 19:19:50 +0100 Subject: [PATCH] feat: Enhance CLI and GUI to support configurable game data directory persistence Signed-off-by: Hans Kokx --- apps/wolf_3d_cli/bin/main.dart | 69 ++++++++++--- apps/wolf_3d_cli/pubspec.yaml | 2 +- apps/wolf_3d_gui/lib/main.dart | 11 +-- apps/wolf_3d_gui/pubspec.yaml | 4 +- .../managers/desktop_windowing_support.dart | 20 ++++ .../game_data_directory_persistence.dart | 4 + .../game_data_directory_persistence_io.dart | 99 +++++++++++++++++++ .../game_data_directory_persistence_stub.dart | 14 +++ .../lib/screens/no_game_data_screen.dart | 72 +++++++++++--- .../lib/widgets/wolf3d_app.dart | 12 ++- .../wolf_3d_flutter/lib/wolf_3d_flutter.dart | 52 ++++++---- packages/wolf_3d_flutter/pubspec.yaml | 1 - .../game_data_directory_persistence_test.dart | 99 +++++++++++++++++++ .../test/wolf_3d_flutter_debug_mode_test.dart | 9 +- 14 files changed, 402 insertions(+), 66 deletions(-) create mode 100644 packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence.dart create mode 100644 packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_io.dart create mode 100644 packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_stub.dart create mode 100644 packages/wolf_3d_flutter/test/game_data_directory_persistence_test.dart diff --git a/apps/wolf_3d_cli/bin/main.dart b/apps/wolf_3d_cli/bin/main.dart index 3576742..6ad66ef 100644 --- a/apps/wolf_3d_cli/bin/main.dart +++ b/apps/wolf_3d_cli/bin/main.dart @@ -6,6 +6,7 @@ library; import 'dart:io'; +import 'package:args/args.dart'; import 'package:wolf_3d_cli/cli_game_loop.dart'; import 'package:wolf_3d_dart/wolf_3d_audio.dart'; import 'package:wolf_3d_dart/wolf_3d_data.dart'; @@ -21,28 +22,66 @@ void exitCleanly(int code) { exit(code); } -/// Launches the CLI renderer against the bundled retail asset set. -void main() async { - stdout.write("Discovering game data..."); - // Resolve the asset package relative to this executable so the CLI can run - // from the repo without additional configuration. - final scriptUri = Platform.script; +/// Launches the CLI renderer using discoverable or user-provided game data. +void main(List arguments) async { + final argParser = ArgParser() + ..addOption( + 'data-directory', + abbr: 'd', + valueHelp: 'path', + help: 'Directory containing Wolf3D data files.', + ) + ..addFlag( + 'help', + abbr: 'h', + negatable: false, + help: 'Show usage information.', + ); - final targetUri = scriptUri.resolve( - '../../../packages/wolf_3d_assets/assets/retail', - ); - final targetPath = targetUri.toFilePath(); + late final ArgResults parsedArgs; + try { + parsedArgs = argParser.parse(arguments); + } on FormatException catch (e) { + stderr.writeln(e.message); + stderr.writeln('Usage: wolf_3d_cli [options]'); + stderr.writeln(argParser.usage); + exitCleanly(64); + } + + if (parsedArgs.flag('help')) { + stdout.writeln('Usage: wolf_3d_cli [options]'); + stdout.writeln(argParser.usage); + exitCleanly(0); + } + + final String? rawPath = parsedArgs.option('data-directory'); + final String? dataDirectory = rawPath != null && rawPath.trim().isNotEmpty + ? rawPath.trim() + : null; + + if (dataDirectory != null) { + stdout.write('Discovering game data in "$dataDirectory"...'); + } else { + stdout.write('Discovering game data...'); + } final availableGames = await WolfensteinLoader.discover( - directoryPath: targetPath, + directoryPath: dataDirectory, recursive: true, ); if (availableGames.isEmpty) { - stderr.writeln('\nNo Wolf3D game files were found at: $targetPath'); - stderr.writeln( - 'Please provide valid game data files before starting the CLI host.', - ); + if (dataDirectory == null) { + stderr.writeln('\nNo Wolf3D game data was discovered.'); + stderr.writeln('Provide a game-data directory with one of these flags:'); + stderr.writeln(' --data-directory '); + stderr.writeln(' -d '); + } else { + stderr.writeln('\nNo Wolf3D game files were found at: $dataDirectory'); + stderr.writeln( + 'Please provide valid game data files before starting the CLI host.', + ); + } exitCleanly(1); } diff --git a/apps/wolf_3d_cli/pubspec.yaml b/apps/wolf_3d_cli/pubspec.yaml index 5da593b..2e77b89 100644 --- a/apps/wolf_3d_cli/pubspec.yaml +++ b/apps/wolf_3d_cli/pubspec.yaml @@ -8,5 +8,5 @@ environment: resolution: workspace dependencies: + args: ^2.7.0 wolf_3d_dart: - wolf_3d_assets: diff --git a/apps/wolf_3d_gui/lib/main.dart b/apps/wolf_3d_gui/lib/main.dart index a0f1d98..2b40a33 100644 --- a/apps/wolf_3d_gui/lib/main.dart +++ b/apps/wolf_3d_gui/lib/main.dart @@ -7,24 +7,19 @@ library; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:window_manager/window_manager.dart'; import 'package:wolf_3d_flutter/wolf_3d_flutter.dart'; /// Creates the application shell after loading available Wolf3D data sets. void main() async { WidgetsFlutterBinding.ensureInitialized(); - if (supportsDesktopWindowing) { - await windowManager.ensureInitialized(); - } - - final Wolf3dFlutterEngine wolf3d = await Wolf3dFlutterEngine().init( + final Wolf3dFlutterEngine wolf3d = await Wolf3dFlutterEngine( debug: kDebugMode, - ); + ).init(); runApp( MaterialApp( - home: Wolf3dApp(wolf3d: wolf3d), + home: Wolf3dApp(engine: wolf3d), ), ); } diff --git a/apps/wolf_3d_gui/pubspec.yaml b/apps/wolf_3d_gui/pubspec.yaml index 14cb286..0ea1cca 100644 --- a/apps/wolf_3d_gui/pubspec.yaml +++ b/apps/wolf_3d_gui/pubspec.yaml @@ -9,9 +9,7 @@ environment: resolution: workspace dependencies: - wolf_3d_dart: - wolf_3d_flutter: any - window_manager: ^0.5.1 + wolf_3d_flutter: flutter: sdk: flutter diff --git a/packages/wolf_3d_flutter/lib/managers/desktop_windowing_support.dart b/packages/wolf_3d_flutter/lib/managers/desktop_windowing_support.dart index 8c62c3e..912b0d1 100644 --- a/packages/wolf_3d_flutter/lib/managers/desktop_windowing_support.dart +++ b/packages/wolf_3d_flutter/lib/managers/desktop_windowing_support.dart @@ -1,6 +1,8 @@ library; import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:window_manager/window_manager.dart'; /// Whether desktop window-management APIs are expected to work on this host. bool get supportsDesktopWindowing { @@ -15,3 +17,21 @@ bool get supportsDesktopWindowing { _ => false, }; } + +/// Ensures desktop windowing plugin state is initialized when supported. +/// +/// This safely no-ops on non-desktop targets and in hosts where the plugin is +/// not registered. +Future ensureDesktopWindowingInitialized({ + WindowManager? windowing, +}) async { + if (!supportsDesktopWindowing) { + return; + } + + try { + await (windowing ?? windowManager).ensureInitialized(); + } on MissingPluginException { + // No-op on hosts where the window manager plugin is unavailable. + } +} diff --git a/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence.dart b/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence.dart new file mode 100644 index 0000000..e1dd8ba --- /dev/null +++ b/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence.dart @@ -0,0 +1,4 @@ +library; + +export 'game_data_directory_persistence_stub.dart' + if (dart.library.io) 'game_data_directory_persistence_io.dart'; diff --git a/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_io.dart b/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_io.dart new file mode 100644 index 0000000..cadcbc0 --- /dev/null +++ b/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_io.dart @@ -0,0 +1,99 @@ +library; + +import 'dart:convert'; +import 'dart:io'; + +/// Persists the configured game-data directory path as JSON. +class DefaultGameDataDirectoryPersistence { + DefaultGameDataDirectoryPersistence({String? filePath}) + : _filePath = filePath; + + final String? _filePath; + String? _resolvedPath; + + /// Absolute JSON file path used for persistence. + String get filePath { + if (_resolvedPath != null) { + return _resolvedPath!; + } + + if (_filePath != null && _filePath.isNotEmpty) { + _resolvedPath = _filePath; + return _resolvedPath!; + } + + _resolvedPath = '$platformConfigDir/data_source.json'; + return _resolvedPath!; + } + + /// Loads a previously persisted data-directory path. + Future loadDataDirectory() async { + try { + final file = File(filePath); + if (!await file.exists()) { + return null; + } + + final raw = await file.readAsString(); + if (raw.isEmpty) { + return null; + } + + final decoded = jsonDecode(raw); + if (decoded is! Map) { + return null; + } + + final Object? value = decoded['dataDirectory']; + if (value is! String) { + return null; + } + + final normalized = value.trim(); + return normalized.isEmpty ? null : normalized; + } catch (_) { + return null; + } + } + + /// Persists [directoryPath] for future startups. + Future saveDataDirectory(String? directoryPath) async { + try { + final normalized = directoryPath?.trim(); + final file = File(filePath); + + await file.parent.create(recursive: true); + if (normalized == null || normalized.isEmpty) { + if (await file.exists()) { + await file.delete(); + } + return; + } + + final payload = jsonEncode({ + 'dataDirectory': normalized, + }); + await file.writeAsString(payload, flush: true); + } catch (_) { + // Best-effort only. + } + } + + String get platformConfigDir { + if (Platform.isLinux) { + final String xdg = Platform.environment['XDG_CONFIG_HOME'] ?? ''; + final String home = Platform.environment['HOME'] ?? '.'; + return xdg.isNotEmpty ? '$xdg/wolf3d' : '$home/.config/wolf3d'; + } + if (Platform.isMacOS) { + final String home = Platform.environment['HOME'] ?? '.'; + return '$home/Library/Application Support/wolf3d'; + } + if (Platform.isWindows) { + final String appData = Platform.environment['APPDATA'] ?? '.'; + return '$appData/wolf3d'; + } + final String home = Platform.environment['HOME'] ?? '.'; + return '$home/.config/wolf3d'; + } +} diff --git a/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_stub.dart b/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_stub.dart new file mode 100644 index 0000000..03f76ef --- /dev/null +++ b/packages/wolf_3d_flutter/lib/managers/game_data_directory_persistence_stub.dart @@ -0,0 +1,14 @@ +library; + +/// No-op persistence used on platforms without `dart:io` support. +class DefaultGameDataDirectoryPersistence { + DefaultGameDataDirectoryPersistence({String? filePath}); + + /// Loads a previously persisted data-directory path. + Future loadDataDirectory() async { + return null; + } + + /// Persists [directoryPath] for future startups. + Future saveDataDirectory(String? directoryPath) async {} +} diff --git a/packages/wolf_3d_flutter/lib/screens/no_game_data_screen.dart b/packages/wolf_3d_flutter/lib/screens/no_game_data_screen.dart index bd8f225..8c53497 100644 --- a/packages/wolf_3d_flutter/lib/screens/no_game_data_screen.dart +++ b/packages/wolf_3d_flutter/lib/screens/no_game_data_screen.dart @@ -1,15 +1,42 @@ library; import 'package:flutter/material.dart'; +import 'package:wolf_3d_dart/wolf_3d_data_types.dart'; +import 'package:wolf_3d_dart/wolf_3d_menu.dart'; /// Fallback screen shown when no Wolf3D game data files are discovered. class NoGameDataScreen extends StatelessWidget { - const NoGameDataScreen({super.key}); + const NoGameDataScreen({ + super.key, + this.configuredDataDirectory, + }); + + /// Previously configured external game-data directory, if any. + final String? configuredDataDirectory; + + static Color _colorFromVgaIndex(int index) { + final int packed = ColorPalette.vga32Bit[index]; // 0xAABBGGRR + final int r = packed & 0xFF; + final int g = (packed >> 8) & 0xFF; + final int b = (packed >> 16) & 0xFF; + return Color((0xFF << 24) | (r << 16) | (g << 8) | b); + } + + static final Color _backgroundColor = _colorFromVgaIndex(111); + static final Color _panelColor = _colorFromVgaIndex(103); + static final Color _borderColor = _colorFromVgaIndex(87); + static final Color _titleColor = _colorFromVgaIndex( + WolfMenuPalette.headerTextIndex, + ); + static final Color _bodyColor = _colorFromVgaIndex( + WolfMenuPalette.unselectedTextIndex, + ); + static final Color _emphasisColor = _colorFromVgaIndex(10); @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: const Color(0xFF140000), + backgroundColor: _backgroundColor, body: Center( child: Padding( padding: const EdgeInsets.all(24), @@ -17,10 +44,10 @@ class NoGameDataScreen extends StatelessWidget { constraints: const BoxConstraints(maxWidth: 640), child: DecoratedBox( decoration: BoxDecoration( - color: const Color(0xFF590002), - border: Border.all(color: const Color(0xFFB00000), width: 2), + color: _panelColor, + border: Border.all(color: _borderColor, width: 2), ), - child: const Padding( + child: Padding( padding: EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, @@ -29,25 +56,44 @@ class NoGameDataScreen extends StatelessWidget { Text( 'WOLF3D DATA NOT FOUND', style: TextStyle( - color: Color(0xFFFFF700), + color: _titleColor, fontSize: 24, fontWeight: FontWeight.bold, ), ), - SizedBox(height: 16), + const SizedBox(height: 16), Text( 'No game files were discovered.\n\n' - 'Add Wolfenstein 3D data files to one of these locations:\n' - '- packages/wolf_3d_assets/assets/retail\n' - '- packages/wolf_3d_assets/assets/shareware\n' - '- or a discoverable local game-data folder.\n\n' - 'Restart the app after adding the files.', + 'Select a game-data directory in setup.', style: TextStyle( - color: Colors.white, + color: _bodyColor, fontSize: 15, height: 1.4, ), ), + const SizedBox(height: 12), + Text( + 'Once all required files are present, the game starts automatically.', + style: TextStyle( + color: _emphasisColor, + fontSize: 14, + height: 1.35, + fontWeight: FontWeight.w600, + ), + ), + if (configuredDataDirectory != null && + configuredDataDirectory!.trim().isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 12), + child: Text( + 'Configured data directory: ${configuredDataDirectory!.trim()}', + style: TextStyle( + color: _bodyColor, + fontSize: 13, + height: 1.3, + ), + ), + ), ], ), ), diff --git a/packages/wolf_3d_flutter/lib/widgets/wolf3d_app.dart b/packages/wolf_3d_flutter/lib/widgets/wolf3d_app.dart index 5b4a559..aed5398 100644 --- a/packages/wolf_3d_flutter/lib/widgets/wolf3d_app.dart +++ b/packages/wolf_3d_flutter/lib/widgets/wolf3d_app.dart @@ -7,17 +7,19 @@ import 'package:wolf_3d_flutter/wolf_3d_flutter.dart'; /// host screens. class Wolf3dApp extends StatelessWidget { /// Shared initialized facade that owns game data, input, and audio services. - final Wolf3dFlutterEngine wolf3d; + final Wolf3dFlutterEngine engine; const Wolf3dApp({ super.key, - required this.wolf3d, + required this.engine, }); @override Widget build(BuildContext context) { - return wolf3d.availableGames.isEmpty - ? const NoGameDataScreen() - : GameScreen(wolf3d: wolf3d); + return engine.availableGames.isEmpty + ? NoGameDataScreen( + configuredDataDirectory: engine.configuredDataDirectory, + ) + : GameScreen(wolf3d: engine); } } diff --git a/packages/wolf_3d_flutter/lib/wolf_3d_flutter.dart b/packages/wolf_3d_flutter/lib/wolf_3d_flutter.dart index bbe74e3..c2e1307 100644 --- a/packages/wolf_3d_flutter/lib/wolf_3d_flutter.dart +++ b/packages/wolf_3d_flutter/lib/wolf_3d_flutter.dart @@ -7,13 +7,17 @@ import 'package:wolf_3d_dart/wolf_3d_data.dart'; import 'package:wolf_3d_dart/wolf_3d_data_types.dart'; import 'package:wolf_3d_dart/wolf_3d_engine.dart'; import 'package:wolf_3d_flutter/audio/wolf3d_platform_audio.dart'; +import 'package:wolf_3d_flutter/managers/desktop_windowing_support.dart' + as desktop_windowing_support; +import 'package:wolf_3d_flutter/managers/game_data_directory_persistence.dart'; import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart'; export 'package:wolf_3d_dart/wolf_3d_audio.dart' show DebugMusicPlayer; export 'audio/wolf3d_platform_audio.dart' show Wolf3dPlatformAudio; -export 'managers/desktop_windowing_support.dart' show supportsDesktopWindowing; export 'managers/game_app_lifecycle_manager.dart' show GameAppLifecycleManager; +export 'managers/game_data_directory_persistence.dart' + show DefaultGameDataDirectoryPersistence; export 'managers/game_display_manager.dart' show GameDisplayManager; export 'managers/game_persistence_manager.dart' show GamePersistenceManager; export 'managers/game_renderer_mode_manager.dart' @@ -44,12 +48,26 @@ export 'widgets/wolf_menu_shell.dart' show WolfMenuShell; class Wolf3dFlutterEngine extends Wolf3dEngine { /// Creates an empty facade that must be initialized with [init]. Wolf3dFlutterEngine({ + bool debug = false, EngineAudio? audioBackend, Wolf3dFlutterInput? inputBackend, - }) : super( + DefaultGameDataDirectoryPersistence? dataDirectoryPersistence, + }) : dataDirectoryPersistence = + dataDirectoryPersistence ?? DefaultGameDataDirectoryPersistence(), + super( audio: audioBackend ?? Wolf3dPlatformAudio(), input: inputBackend ?? Wolf3dFlutterInput(), - ); + ) { + if (debug) { + enableDebug(); + } + } + + /// Persists and restores the preferred external game-data directory. + final DefaultGameDataDirectoryPersistence dataDirectoryPersistence; + + /// Last configured/loaded external game-data directory path. + String? configuredDataDirectory; /// Shared Flutter input adapter reused by gameplay screens. @override @@ -63,18 +81,24 @@ class Wolf3dFlutterEngine extends Wolf3dEngine { } /// Initializes the engine by loading available game data. - /// - /// Set [debug] to `true` to explicitly enable host-level debug affordances. Future init({ String? directory, - bool debug = false, }) async { - if (debug) { - enableDebug(); - } + await desktop_windowing_support.ensureDesktopWindowingInitialized(); await audio.init(); availableGames.clear(); + final String? requestedDirectory = directory?.trim(); + final String? resolvedDirectory = + requestedDirectory != null && requestedDirectory.isNotEmpty + ? requestedDirectory + : await dataDirectoryPersistence.loadDataDirectory(); + configuredDataDirectory = resolvedDirectory; + + if (requestedDirectory != null && requestedDirectory.isNotEmpty) { + await dataDirectoryPersistence.saveDataDirectory(requestedDirectory); + } + // Bundled assets let the GUI work out of the box on supported platforms. final versionsToTry = [ (version: GameVersion.retail, path: 'retail'), @@ -106,10 +130,10 @@ class Wolf3dFlutterEngine extends Wolf3dEngine { // On non-web platforms, also scan the local filesystem for user-supplied // data folders so the host can pick up extra versions automatically. - if (!kIsWeb) { + if (!kIsWeb && resolvedDirectory != null) { try { final externalGames = await WolfensteinLoader.discover( - directoryPath: directory, + directoryPath: resolvedDirectory, recursive: true, ); for (var entry in externalGames.entries) { @@ -135,9 +159,3 @@ class Wolf3dFlutterEngine extends Wolf3dEngine { } } } - -/// Backward-compatible alias for the previous Flutter host facade name. -typedef Wolf3dFlutter = Wolf3dFlutterEngine; - -/// Backward-compatible alias for the legacy Flutter host facade name. -typedef Wolf3d = Wolf3dFlutterEngine; diff --git a/packages/wolf_3d_flutter/pubspec.yaml b/packages/wolf_3d_flutter/pubspec.yaml index cad57ef..9a1da9b 100644 --- a/packages/wolf_3d_flutter/pubspec.yaml +++ b/packages/wolf_3d_flutter/pubspec.yaml @@ -13,7 +13,6 @@ dependencies: wolf_3d_dart: flutter: sdk: flutter - wolf_3d_assets: any audioplayers: ^6.6.0 window_manager: ^0.5.1 diff --git a/packages/wolf_3d_flutter/test/game_data_directory_persistence_test.dart b/packages/wolf_3d_flutter/test/game_data_directory_persistence_test.dart new file mode 100644 index 0000000..56f345f --- /dev/null +++ b/packages/wolf_3d_flutter/test/game_data_directory_persistence_test.dart @@ -0,0 +1,99 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:wolf_3d_dart/wolf_3d_data_types.dart'; +import 'package:wolf_3d_dart/wolf_3d_engine.dart'; +import 'package:wolf_3d_flutter/wolf_3d_flutter.dart'; + +class _NoopAudio implements EngineAudio { + @override + WolfensteinData? activeGame; + + @override + Future debugSoundTest() async {} + + @override + Future init() async {} + + @override + void playLevelMusic(Music music) {} + + @override + void playMenuMusic() {} + + @override + void playSoundEffect(SoundEffect effect) {} + + @override + void playSoundEffectId(int sfxId) {} + + @override + Future stopAllAudio() async {} + + @override + void stopMusic() {} + + @override + void dispose() {} +} + +void main() { + group('DefaultGameDataDirectoryPersistence', () { + test('saves and loads configured directory', () async { + final tempDir = await Directory.systemTemp.createTemp( + 'wolf3d-data-config-', + ); + addTearDown(() async { + if (await tempDir.exists()) { + await tempDir.delete(recursive: true); + } + }); + + final persistence = DefaultGameDataDirectoryPersistence( + filePath: '${tempDir.path}/data_source.json', + ); + + await persistence.saveDataDirectory('/tmp/wolf-data'); + + final loaded = await persistence.loadDataDirectory(); + expect(loaded, '/tmp/wolf-data'); + }); + + test('clears persisted path when saving null', () async { + final tempDir = await Directory.systemTemp.createTemp( + 'wolf3d-data-config-', + ); + addTearDown(() async { + if (await tempDir.exists()) { + await tempDir.delete(recursive: true); + } + }); + + final path = '${tempDir.path}/data_source.json'; + final persistence = DefaultGameDataDirectoryPersistence(filePath: path); + + await persistence.saveDataDirectory('/tmp/wolf-data'); + await persistence.saveDataDirectory(null); + + expect(await File(path).exists(), isFalse); + expect(await persistence.loadDataDirectory(), isNull); + }); + }); + + testWidgets('Wolf3dApp forwards configured directory to no-data screen', ( + tester, + ) async { + final wolf3d = Wolf3dFlutterEngine(audioBackend: _NoopAudio()) + ..configuredDataDirectory = '/tmp/wolf-data'; + + await tester.pumpWidget( + MaterialApp( + home: Wolf3dApp(engine: wolf3d), + ), + ); + + expect(find.textContaining('Configured data directory:'), findsOneWidget); + expect(find.textContaining('/tmp/wolf-data'), findsOneWidget); + }); +} diff --git a/packages/wolf_3d_flutter/test/wolf_3d_flutter_debug_mode_test.dart b/packages/wolf_3d_flutter/test/wolf_3d_flutter_debug_mode_test.dart index ff9c5a0..d157440 100644 --- a/packages/wolf_3d_flutter/test/wolf_3d_flutter_debug_mode_test.dart +++ b/packages/wolf_3d_flutter/test/wolf_3d_flutter_debug_mode_test.dart @@ -55,10 +55,13 @@ void main() { expect(wolf3d.isDebugEnabled, isTrue); }); - test('init(debug: true) enables debug mode', () async { - final wolf3d = Wolf3dFlutterEngine(audioBackend: _NoopAudio()); + test('constructor(debug: true) enables debug mode', () async { + final wolf3d = Wolf3dFlutterEngine( + audioBackend: _NoopAudio(), + debug: true, + ); - await wolf3d.init(debug: true); + await wolf3d.init(); expect(wolf3d.isDebugEnabled, isTrue); });