示例#1
0
        public void addListener(ImageStreamListener listener)
        {
            if (_completer != null)
            {
                _completer.addListener(listener);
                return;
            }

            if (_listeners == null)
            {
                _listeners = new List <ImageStreamListener>();
            }

            _listeners.Add(listener);
        }
        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);
        }
示例#3
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);
        }