Files
flutter_lua_runtime/lib/runtime/resources/game_resource_cache.dart
2026-06-07 22:53:58 +08:00

67 lines
1.7 KiB
Dart

part of 'game_resource_manager.dart';
extension _GameResourceManagerCache on GameResourceManager {
void _touch(_ImageResourceRecord record) {
record.lastUsed = ++_accessCounter;
}
void _enforceImageBudget() {
while (_isOverBudget()) {
final victim = _leastRecentlyUsedEvictableImage();
if (victim == null || !_removeImageRecord(victim)) {
return;
}
}
}
bool _isOverBudget() {
final maxBytes = _maxCacheBytes;
final maxEntries = _maxCacheEntries;
return (maxBytes != null && _cacheBytes > maxBytes) ||
(maxEntries != null && _readyImageCount > maxEntries);
}
int get _readyImageCount => _images.values
.where((record) => record.state == GameResourceState.ready)
.length;
String? _leastRecentlyUsedEvictableImage() {
String? victimPath;
_ImageResourceRecord? victim;
for (final entry in _images.entries) {
final record = entry.value;
if (record.state != GameResourceState.ready || record.refCount > 0) {
continue;
}
if (victim == null || record.lastUsed < victim.lastUsed) {
victim = record;
victimPath = entry.key;
}
}
return victimPath;
}
void _releaseCachedImages() {
_loadLimiter.clearPending();
for (final path in _images.keys.toList(growable: false)) {
_removeImageRecord(path);
}
}
bool _removeImageRecord(String path) {
final record = _images.remove(path);
if (record == null) {
return false;
}
record.state = GameResourceState.disposed;
_cacheBytes -= record.estimatedBytes;
if (_cacheBytes < 0) {
_cacheBytes = 0;
}
record.image?.dispose();
record.image = null;
record.inflight = null;
return true;
}
}