浏览代码

painting -- image

/main
xingwei.zhu 6 年前
当前提交
090a1318
共有 3 个文件被更改,包括 80 次插入46 次删除
  1. 107
      Runtime/painting/image_cache.cs
  2. 16
      Runtime/painting/image_stream.cs
  3. 3
      Samples/UIWidgetSample/AsScreenSample.cs

107
Runtime/painting/image_cache.cs


const int _kDefaultSize = 1000;
const int _kDefaultSizeBytes = 100 << 20; // 100 MiB
readonly Dictionary<object, ImageStreamCompleter> _pendingImages =
new Dictionary<object, ImageStreamCompleter>();
readonly Dictionary<object, _PendingImage> _pendingImages =
new Dictionary<object, _PendingImage>();
readonly Dictionary<object, _CachedImage> _cache = new Dictionary<object, _CachedImage>();
readonly LinkedList<object> _lruKeys = new LinkedList<object>();

public void clear() {
this._cache.Clear();
this._lruKeys.Clear();
this._pendingImages.Clear();
this._lruKeys.Clear();
if (this._pendingImages.TryGetValue(key, out var pendingImage)) {
pendingImage.removeListener();
this._pendingImages.Remove(key);
return true;
}
this._cache.Remove(image.node);
this._cache.Remove(key);
public ImageStreamCompleter putIfAbsent(object key, Func<ImageStreamCompleter> loader) {
public ImageStreamCompleter putIfAbsent(object key, Func<ImageStreamCompleter> loader, ImageErrorListener onError = null) {
if (this._pendingImages.TryGetValue(key, out var result)) {
ImageStreamCompleter result = null;
if (this._pendingImages.TryGetValue(key, out var pendingImage)) {
result = pendingImage.completer;
return result;
}

return image.completer;
}
result = loader();
if (this._maximumSize > 0 && this._maximumSizeBytes > 0) {
D.assert(!this._pendingImages.ContainsKey(key));
this._pendingImages[key] = result;
try {
result = loader();
}
catch (Exception ex) {
if (onError != null) {
onError(ex);
}
else {
throw;
}
}
ImageListener listener = null;
listener = (info, syncCall) => {
result.removeListener(listener);
void listener(ImageInfo info, bool syncCall) {
int imageSize = info?.image == null ? 0 : info.image.height * info.image.width * 4;
_CachedImage cachedImage = new _CachedImage(result, imageSize);
if (this.maximumSizeBytes > 0 && imageSize > this.maximumSizeBytes) {
this._maximumSizeBytes = imageSize + 1000;
}
this._currentSizeBytes += imageSize;
D.assert(this._pendingImages.ContainsKey(key));
if (this._pendingImages.TryGetValue(key, out var loadedPendingImage)) {
loadedPendingImage.removeListener();
}
D.assert(!this._cache.ContainsKey(key));
this._cache[key] = cachedImage;
cachedImage.node = this._lruKeys.AddLast(key);
this._checkCacheSize();
}
int imageSize = info?.image == null ? 0 : info.image.width * info.image.height * 4;
_CachedImage cachedImage = new _CachedImage {
completer = result,
sizeBytes = imageSize,
};
// If the image is bigger than the maximum cache size, and the cache size
// is not zero, then increase the cache size to the size of the image plus
// some change.
if (this._maximumSizeBytes > 0 && imageSize > this._maximumSizeBytes) {
this._maximumSizeBytes = imageSize + 1000;
}
this._currentSizeBytes += imageSize;
D.assert(!this._cache.ContainsKey(key));
this._cache[key] = cachedImage;
cachedImage.node = this._lruKeys.AddLast(key);
this._checkCacheSize();
};
if (this.maximumSize > 0 && this.maximumSizeBytes > 0) {
this._pendingImages[key] = new _PendingImage(result, listener);
result.addListener(listener);
}

}
class _CachedImage {
public _CachedImage(ImageStreamCompleter completer, int sizeBytes) {
this.completer = completer;
this.sizeBytes = sizeBytes;
}
}
class _PendingImage {
public _PendingImage(
ImageStreamCompleter completer,
ImageListener listener
) {
this.completer = completer;
this.listener = listener;
}
public readonly ImageStreamCompleter completer;
public readonly ImageListener listener;
public void removeListener() {
this.completer.removeListener(this.listener);
}
}
}

16
Runtime/painting/image_stream.cs


public ImageInfo currentImage;
public UIWidgetsErrorDetails currentError;
protected bool hasListeners {
get { return this._listeners.isNotEmpty(); }
}
public virtual void addListener(ImageListener listener, ImageErrorListener onError = null) {
this._listeners.Add(new _ImageListenerPair {listener = listener, errorListener = onError});

catch (Exception ex) {
UIWidgetsError.reportError(
new UIWidgetsErrorDetails(
context: "by an image error listener",
context: "when reporting an error to an image listener",
library: "image resource service",
exception: ex
)

}
void _handleAppFrame(TimeSpan timestamp) {
if (!this._hasActiveListeners) {
if (!this.hasListeners) {
return;
}

this._framesEmitted += 1;
}
bool _hasActiveListeners {
get { return this._listeners.isNotEmpty(); }
}
if (!this._hasActiveListeners && this._codec != null) {
if (!this.hasListeners && this._codec != null) {
this._decodeNextFrameAndSchedule();
}

public override void removeListener(ImageListener listener) {
base.removeListener(listener);
if (!this._hasActiveListeners) {
if (!this.hasListeners) {
this._timer?.cancel();
this._timer = null;
}

3
Samples/UIWidgetSample/AsScreenSample.cs


fontSize: 16
),
selectionColor: Color.fromARGB(255, 255, 0, 0),
cursorColor: Color.fromARGB(255, 0, 0, 0)
cursorColor: Color.fromARGB(255, 0, 0, 0),
backgroundCursorColor: Colors.blue
)
),
new Container(

正在加载...
取消
保存