feat: add Lua runtime storage API
This commit is contained in:
94
lib/runtime/storage/runtime_storage_manager.dart
Normal file
94
lib/runtime/storage/runtime_storage_manager.dart
Normal file
@@ -0,0 +1,94 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class RuntimeStorageManager {
|
||||
RuntimeStorageManager._(this._file, this._values);
|
||||
|
||||
final File _file;
|
||||
final Map<String, Object?> _values;
|
||||
|
||||
static Future<RuntimeStorageManager> create({required String gameId}) async {
|
||||
final root = await getApplicationSupportDirectory();
|
||||
final directory = Directory(p.join(root.path, 'flame_lua_storage'));
|
||||
if (!directory.existsSync()) {
|
||||
directory.createSync(recursive: true);
|
||||
}
|
||||
|
||||
final file = File(p.join(directory.path, '$gameId.json'));
|
||||
if (!file.existsSync()) {
|
||||
return RuntimeStorageManager._(file, <String, Object?>{});
|
||||
}
|
||||
|
||||
try {
|
||||
final raw = jsonDecode(file.readAsStringSync());
|
||||
if (raw is Map) {
|
||||
return RuntimeStorageManager._(
|
||||
file,
|
||||
Map<String, Object?>.from(raw),
|
||||
);
|
||||
}
|
||||
} catch (_) {
|
||||
// Corrupt storage should not prevent a game from loading.
|
||||
}
|
||||
|
||||
return RuntimeStorageManager._(file, <String, Object?>{});
|
||||
}
|
||||
|
||||
Object? getValue(String key, [Object? defaultValue]) {
|
||||
if (!_values.containsKey(key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return _values[key];
|
||||
}
|
||||
|
||||
bool setValue(String key, Object? value) {
|
||||
_values[key] = _normalize(value);
|
||||
_flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove(String key) {
|
||||
final removed = _values.remove(key) != null;
|
||||
if (removed) {
|
||||
_flush();
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
bool clear() {
|
||||
if (_values.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
_values.clear();
|
||||
_flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<String, Object?> debugJson() => Map<String, Object?>.from(_values);
|
||||
|
||||
Object? _normalize(Object? value) {
|
||||
if (value == null || value is bool || value is num || value is String) {
|
||||
return value;
|
||||
}
|
||||
if (value is List) {
|
||||
return value.map(_normalize).toList(growable: false);
|
||||
}
|
||||
if (value is Map) {
|
||||
return {
|
||||
for (final entry in value.entries) entry.key.toString(): _normalize(entry.value),
|
||||
};
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
void _flush() {
|
||||
final parent = _file.parent;
|
||||
if (!parent.existsSync()) {
|
||||
parent.createSync(recursive: true);
|
||||
}
|
||||
_file.writeAsStringSync(jsonEncode(_values));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user