Beispiel #1
0
        public ImageStreamCompleter putIfAbsent(object key, Func <ImageStreamCompleter> loader)
        {
            D.assert(key != null);
            D.assert(loader != null);

            if (this._pendingImages.TryGetValue(key, out var result))
            {
                return(result);
            }

            if (this._cache.TryGetValue(key, out var image))
            {
                // put to the MRU position
                this._lruKeys.Remove(image.node);
                image.node = this._lruKeys.AddLast(key);
                return(image.completer);
            }

            result = loader();

            if (this._maximumSize > 0 && this._maximumSizeBytes > 0)
            {
                D.assert(!this._pendingImages.ContainsKey(key));
                this._pendingImages[key] = result;

                ImageListener listener = null;
                listener = (info, syncCall) => {
                    result.removeListener(listener);

                    D.assert(this._pendingImages.ContainsKey(key));
                    this._pendingImages.Remove(key);

                    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();
                };
                result.addListener(listener);
            }

            return(result);
        }
 void _touch(Object key, _CachedImage image)
 {
     // D.assert(foundation_.kReleaseMode);
     if (image.sizeBytes != null && image.sizeBytes <= maximumSizeBytes)
     {
         _currentSizeBytes += image.sizeBytes ?? 0;
         _cache[key]        = image;
         // _checkCacheSize(timelineTask);
     }
 }
Beispiel #3
0
        void _checkCacheSize()
        {
            while (this._currentSizeBytes > this._maximumSizeBytes || this._cache.Count > this._maximumSize)
            {
                var node = this._lruKeys.First;
                var key  = node.Value; // get the LRU item

                D.assert(this._cache.ContainsKey(key));
                _CachedImage image = this._cache[key];

                D.assert(node == image.node);
                this._currentSizeBytes -= image.sizeBytes;
                this._cache.Remove(key);
                this._lruKeys.Remove(image.node);
            }

            D.assert(this._currentSizeBytes >= 0);
            D.assert(this._cache.Count <= this.maximumSize);
            D.assert(this._currentSizeBytes <= this.maximumSizeBytes);
        }
        public ImageStreamCompleter putIfAbsent(object key, Func <ImageStreamCompleter> loader,
                                                ImageErrorListener onError = null)
        {
            D.assert(key != null);
            D.assert(loader != null);

            ImageStreamCompleter result = null;

            if (_pendingImages.TryGetValue(key, out var pendingImage))
            {
                result = pendingImage.completer;
                return(result);
            }

            if (_cache.TryGetValue(key, out var image))
            {
                if (image.node != null)
                {
                    _lruKeys.Remove(image.node);
                }
                _trackLiveImage(key, new _LiveImage(image.completer, image.sizeBytes, () => _liveImages.Remove(key)));
                image.node = _lruKeys.AddLast(key);
                return(image.completer);
            }

            _liveImages.TryGetValue(key, out var liveImage);
            if (liveImage != null)
            {
                _touch(key, liveImage);
                return(liveImage.completer);
            }

            try {
                result = loader();
                _trackLiveImage(key, new _LiveImage(result, null, () => _liveImages.Remove(key)));
            }
            catch (Exception ex) {
                if (onError != null)
                {
                    onError(ex);
                }
                else
                {
                    throw;
                }
            }

            bool          listenedOnce          = false;
            _PendingImage untrackedPendingImage = null;

            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);

                _trackLiveImage(
                    key,
                    new _LiveImage(
                        result,
                        imageSize,
                        () => _liveImages.Remove(key)
                        ),
                    debugPutOk: syncCall
                    );
                _PendingImage _pendingImage = untrackedPendingImage ?? _pendingImages.getOrDefault(key);

                _pendingImages.Remove(key);
                if (_pendingImage != null)
                {
                    _pendingImage.removeListener();
                }

                if (untrackedPendingImage == null)
                {
                    _touch(key, cachedImage);
                }

                listenedOnce = true;
            }

            ImageStreamListener streamListener = new ImageStreamListener(listener);

            if (maximumSize > 0 && maximumSizeBytes > 0)
            {
                _pendingImages[key] = new _PendingImage(result, streamListener);
            }
            else
            {
                untrackedPendingImage = new _PendingImage(result, streamListener);
            }

            result.addListener(streamListener);

            return(result);
        }
Beispiel #5
0
        public ImageStreamCompleter putIfAbsent(object key, Func <ImageStreamCompleter> loader,
                                                ImageErrorListener onError = null)
        {
            D.assert(key != null);
            D.assert(loader != null);

            ImageStreamCompleter result = null;

            if (this._pendingImages.TryGetValue(key, out var pendingImage))
            {
                result = pendingImage.completer;
                return(result);
            }

            if (this._cache.TryGetValue(key, out var image))
            {
                // put to the MRU position
                this._lruKeys.Remove(image.node);
                image.node = this._lruKeys.AddLast(key);
                return(image.completer);
            }

            try {
                result = loader();
            }
            catch (Exception ex) {
                if (onError != null)
                {
                    onError(ex);
                }
                else
                {
                    throw;
                }
            }

            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;

                if (this._pendingImages.TryGetValue(key, out var loadedPendingImage))
                {
                    loadedPendingImage.removeListener();
                    this._pendingImages.Remove(key);
                }

                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);
            }

            return(result);
        }