Commit 95f2e981 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Provide an observatory extension to evict resources (#5241)

...so that you can use hot reload mode to update assets.
parent 357f85af
......@@ -62,6 +62,11 @@ abstract class AssetBundle {
/// used with one parser for the lifetime of the asset bundle.
Future<dynamic> loadStructuredData(String key, dynamic parser(String value));
/// If this is a caching asset bundle, and the given key describes a cached
/// asset, then evict the asset from the cache so that the next time it is
/// loaded, the cache will be reread from the asset bundle.
void evict(String key) { }
@override
String toString() => '$runtimeType@$hashCode()';
}
......@@ -101,6 +106,9 @@ class NetworkAssetBundle extends AssetBundle {
return parser(await loadString(key));
}
// TODO(ianh): Once the underlying network logic learns about caching, we
// should implement evict().
@override
String toString() => '$runtimeType@$hashCode($_baseUrl)';
}
......@@ -155,6 +163,12 @@ abstract class CachingAssetBundle extends AssetBundle {
});
return completer.future;
}
@override
void evict(String key) {
_stringCache.remove(key);
_structuredDataCache.remove(key);
}
}
/// An [AssetBundle] that loads resources from a Mojo service.
......
......@@ -7,6 +7,7 @@ import 'dart:async';
import 'package:flutter/foundation.dart';
import 'asset_bundle.dart';
import 'image_cache.dart';
import 'shell.dart';
/// Ensures that the [MojoShell] singleton is created synchronously
......@@ -47,4 +48,21 @@ abstract class ServicesBinding extends BindingBase {
}
}
}
@override
void initServiceExtensions() {
super.initServiceExtensions();
registerStringServiceExtension(
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from the rootBundle cache
// and cause the entire image cache to be cleared. This is used by hot reload mode to clear
// out the cache of resources that have changed.
// TODO(ianh): find a way to only evict affected images, not all images
name: 'evict',
getter: () => '',
setter: (String value) {
rootBundle.evict(value);
imageCache.clear();
}
);
}
}
......@@ -55,6 +55,16 @@ class ImageCache {
}
}
/// Evicts all entries from the cache.
///
/// This is useful if, for instance, the root asset bundle has been updated
/// and therefore new images must be obtained.
// TODO(ianh): Provide a way to target individual images. This is currently non-trivial
// because by the time we get to the imageCache, the keys we're using are opaque.
void clear() {
_cache.clear();
}
/// Returns the previously cached [ImageStream] for the given key, if available;
/// if not, calls the given callback to obtain it first. In either case, the
/// key is moved to the "most recently used" position.
......
......@@ -731,6 +731,28 @@ abstract class State<T extends StatefulWidget> {
@protected
void didUpdateConfig(T oldConfig) { }
/// Called whenever the application is reassembled during debugging.
///
/// This method should rerun any initialization logic that depends on global
/// state, for example, image loading from asset bundles (since the asset
/// bundle may have changed).
///
/// In addition to this method being invoked, it is guaranteed that the
/// [build] method will be invoked when a reassemble is signalled. Most
/// widgets therefore do not need to do anything in the [reassemble] method.
///
/// This function will only be called during development. In release builds,
/// the `ext.flutter.reassemble` hook is not available, and so this code will
/// never execute.
///
/// See also:
///
/// * [BindingBase.reassembleApplication]
/// * [Image], which uses this to reload images
@protected
@mustCallSuper
void reassemble() { }
/// Notify the framework that the internal state of this object has changed.
///
/// Whenever you change the internal state of a [State] object, make the
......@@ -2061,6 +2083,7 @@ class StatefulElement extends ComponentElement {
@override
void _reassemble() {
_builder = state.build;
state.reassemble();
super._reassemble();
}
......
......@@ -205,6 +205,12 @@ class _ImageState extends State<Image> {
super.dependenciesChanged();
}
@override
void reassemble() {
_resolveImage();
super.reassemble();
}
@override
void dispose() {
_imageStream.removeListener(_handleImageChanged);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment