feat: 초기 커밋
- Progress Quest 6.4 Flutter 포팅 프로젝트 - 게임 루프, 상태 관리, UI 구현 - 캐릭터 생성, 인벤토리, 장비, 주문 시스템 - 시장/판매/구매 메커니즘
This commit is contained in:
126
lib/src/features/game/game_session_controller.dart
Normal file
126
lib/src/features/game/game_session_controller.dart
Normal file
@@ -0,0 +1,126 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:askiineverdie/src/core/engine/progress_loop.dart';
|
||||
import 'package:askiineverdie/src/core/engine/progress_service.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
import 'package:askiineverdie/src/core/storage/save_manager.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
enum GameSessionStatus { idle, loading, running, error }
|
||||
|
||||
/// Presentation-friendly wrapper that owns ProgressLoop and SaveManager.
|
||||
class GameSessionController extends ChangeNotifier {
|
||||
GameSessionController({
|
||||
required this.progressService,
|
||||
required this.saveManager,
|
||||
this.autoSaveConfig = const AutoSaveConfig(),
|
||||
Duration tickInterval = const Duration(milliseconds: 50),
|
||||
DateTime Function()? now,
|
||||
}) : _tickInterval = tickInterval,
|
||||
_now = now ?? DateTime.now;
|
||||
|
||||
final ProgressService progressService;
|
||||
final SaveManager saveManager;
|
||||
final AutoSaveConfig autoSaveConfig;
|
||||
|
||||
final Duration _tickInterval;
|
||||
final DateTime Function() _now;
|
||||
|
||||
ProgressLoop? _loop;
|
||||
StreamSubscription<GameState>? _subscription;
|
||||
bool _cheatsEnabled = false;
|
||||
|
||||
GameSessionStatus _status = GameSessionStatus.idle;
|
||||
GameState? _state;
|
||||
String? _error;
|
||||
|
||||
GameSessionStatus get status => _status;
|
||||
GameState? get state => _state;
|
||||
String? get error => _error;
|
||||
bool get isRunning => _status == GameSessionStatus.running;
|
||||
bool get cheatsEnabled => _cheatsEnabled;
|
||||
|
||||
/// 현재 ProgressLoop 인스턴스 (치트 기능용)
|
||||
ProgressLoop? get loop => _loop;
|
||||
|
||||
Future<void> startNew(
|
||||
GameState initialState, {
|
||||
bool cheatsEnabled = false,
|
||||
bool isNewGame = true,
|
||||
}) async {
|
||||
await _stopLoop(saveOnStop: false);
|
||||
|
||||
// 새 게임인 경우 초기화 (프롤로그 태스크 설정)
|
||||
final state = isNewGame
|
||||
? progressService.initializeNewGame(initialState)
|
||||
: initialState;
|
||||
|
||||
_state = state;
|
||||
_error = null;
|
||||
_status = GameSessionStatus.running;
|
||||
_cheatsEnabled = cheatsEnabled;
|
||||
|
||||
_loop = ProgressLoop(
|
||||
initialState: state,
|
||||
progressService: progressService,
|
||||
saveManager: saveManager,
|
||||
autoSaveConfig: autoSaveConfig,
|
||||
tickInterval: _tickInterval,
|
||||
now: _now,
|
||||
cheatsEnabled: cheatsEnabled,
|
||||
);
|
||||
|
||||
_subscription = _loop!.stream.listen((next) {
|
||||
_state = next;
|
||||
notifyListeners();
|
||||
});
|
||||
|
||||
_loop!.start();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> loadAndStart({
|
||||
String? fileName,
|
||||
bool cheatsEnabled = false,
|
||||
}) async {
|
||||
_status = GameSessionStatus.loading;
|
||||
_error = null;
|
||||
notifyListeners();
|
||||
|
||||
final (outcome, loaded) = await saveManager.loadState(fileName: fileName);
|
||||
if (!outcome.success || loaded == null) {
|
||||
_status = GameSessionStatus.error;
|
||||
_error = outcome.error ?? 'Unknown error';
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
await startNew(loaded, cheatsEnabled: cheatsEnabled, isNewGame: false);
|
||||
}
|
||||
|
||||
Future<void> pause({bool saveOnStop = false}) async {
|
||||
await _stopLoop(saveOnStop: saveOnStop);
|
||||
_status = GameSessionStatus.idle;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
final stop = _stopLoop(saveOnStop: false);
|
||||
if (stop != null) {
|
||||
unawaited(stop);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void>? _stopLoop({required bool saveOnStop}) {
|
||||
final loop = _loop;
|
||||
final sub = _subscription;
|
||||
_loop = null;
|
||||
_subscription = null;
|
||||
|
||||
sub?.cancel();
|
||||
if (loop == null) return null;
|
||||
return loop.stop(saveOnStop: saveOnStop);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user