Files
flutter_lua_runtime/lib/runtime/packages/stable_package_store.dart

104 lines
2.9 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import '../game/runtime_options.dart';
import 'game_package.dart';
import 'game_package_manifest.dart';
class StablePackageStore {
const StablePackageStore({
RuntimeOptions runtimeOptions = const RuntimeOptions(),
}) : _runtimeOptions = runtimeOptions;
final RuntimeOptions _runtimeOptions;
Future<Directory> cacheRoot() async {
final support = await getApplicationSupportDirectory();
final root = Directory(p.join(support.path, 'flame_lua_packages'));
root.createSync(recursive: true);
return root;
}
Future<Directory> versionDirectory(String gameId, String version) async {
final root = await cacheRoot();
return Directory(p.join(root.path, gameId, version));
}
Future<void> markStable(GamePackage package) async {
if (package.source != GamePackageSource.file) {
return;
}
final marker = await _markerFile(package.manifest.gameId);
marker.parent.createSync(recursive: true);
final previous = await stablePackage(package.manifest.gameId);
final data = {
'current': package.rootPath,
if (previous != null && previous.rootPath != package.rootPath)
'previous': previous.rootPath,
};
final temporary = File('${marker.path}.tmp');
temporary.writeAsStringSync(
const JsonEncoder.withIndent(' ').convert(data),
);
if (marker.existsSync()) {
marker.deleteSync();
}
temporary.renameSync(marker.path);
}
Future<GamePackage?> stablePackage(String gameId) async {
final data = await _readMarker(gameId);
return _packageFromPath(data?['current']);
}
Future<GamePackage?> previousStablePackage(String gameId) async {
final data = await _readMarker(gameId);
return _packageFromPath(data?['previous']);
}
Future<File> _markerFile(String gameId) async {
final root = await cacheRoot();
return File(p.join(root.path, gameId, 'stable.json'));
}
Future<Map<String, Object?>?> _readMarker(String gameId) async {
final marker = await _markerFile(gameId);
if (!marker.existsSync()) {
return null;
}
final source = await marker.readAsString();
if (source.trim().isEmpty) {
return null;
}
try {
final value = jsonDecode(source);
if (value is Map) {
return Map<String, Object?>.from(value);
}
} catch (_) {
return null;
}
return null;
}
GamePackage? _packageFromPath(Object? pathValue) {
if (pathValue is! String || pathValue.isEmpty) {
return null;
}
final manifestFile = File(p.join(pathValue, 'manifest.json'));
if (!manifestFile.existsSync()) {
return null;
}
return GamePackage.file(
rootPath: pathValue,
manifest: GamePackageManifest.fromJsonString(
manifestFile.readAsStringSync(),
),
runtimeLuaRoot: _runtimeOptions.runtimeLuaRoot,
);
}
}