/// <summary> /// Requests loading the image of <paramref name="size"/> located on <paramref name="uri"/>. /// </summary> /// <param name="uri"> /// An uri of the image to load. /// </param> /// <param name="size"> /// The desired size of the image. /// </param> /// <returns> /// Returns an observable sequence which contains an image(s) of <paramref name="size"/> loaded using <paramref name="uri"/>. /// </returns> /// <remarks> /// Override this method to provide concrete logic of loading the image per each <see cref="BaseImageLoader"/>. /// </remarks> protected override IObservable<ImageInfo> WhenLoadedInternal(Uri uri, Size size) { var result = Observable.Create<ImageInfo>(observer => { var imageLoadContext = new ImageLoadContext(uri, size, observer); this.downloadManager.EnqeueReqeust(imageLoadContext); return () => this.downloadManager.DequeueRequest(imageLoadContext); }); return result; }
/// <summary> /// Requests loading the image of <paramref name="size"/> located on <paramref name="uri"/>. /// </summary> /// <param name="uri"> /// An uri of the image to load. /// </param> /// <param name="size"> /// The desired size of the image. /// </param> /// <returns> /// Returns an observable sequence which contains an image(s) of <paramref name="size"/> loaded using <paramref name="uri"/>. /// </returns> /// <remarks> /// The observable sequence may generate several instances of same image but with different size. For example, /// there cam be a smaller sample of the requested image in the local cache, so this image will be returned immediatly while the image of requested /// size is loading. Once the image of the desired size is loaded, it will be pushed into the same observable sequence. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="uri"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="size"/> has non positive width or height. /// </exception> public IObservable<ImageInfo> WhenLoaded(Uri uri, Size size) { if (uri == null) { throw new ArgumentNullException("uri"); } if (size == default(Size) || size.Width <= 0 || size.Height <= 0) { throw new ArgumentException("The size should have positive width and height", "size"); } return this.WhenLoaded(uri, size, new Size(0, 0)); }
protected override IObservable<ImageInfo> WhenLoadedInternal(Uri uri, Size size) { return Observable.Create<ImageInfo>(observer => { if (imageData != null) { var imageInfo = new ImageInfo(uri, size, imageData) { ForceFallback = true }; observer.OnNext(imageInfo); } observer.OnCompleted(); return () => { }; }); }
public ImageLoadContext(Uri uri, Size size, IObserver<ImageInfo> observer) { this.Uri = uri; this.Size = size; this.Observer = observer; }
public ImageInfo(Uri uri, Size size, byte[] data) { this.Uri = uri; this.Size = size; this.Data = data; }
internal ImageInfo WithSize(Size size) { this.Size = size; return this; }
internal bool IsFittedIn(Size size) { return this.Size.Width >= size.Width || this.Size.Height >= size.Height; }
/// <summary> /// Requests loading the image of <paramref name="size"/> located on <paramref name="uri"/>. /// </summary> /// <param name="uri"> /// An uri of the image to load. /// </param> /// <param name="size"> /// The desired size of the image. /// </param> /// <returns> /// Returns an observable sequence which contains an image(s) of <paramref name="size"/> loaded using <paramref name="uri"/>. /// </returns> /// <remarks> /// Override this method to provide concrete logic of loading the image per each <see cref="BaseImageLoader"/>. /// </remarks> protected abstract IObservable<ImageInfo> WhenLoadedInternal(Uri uri, Size size);
/// <summary> /// Requests loading the image of <paramref name="size"/> located on <paramref name="uri"/>. /// </summary> /// <param name="uri"> /// An uri of the image to load. /// </param> /// <param name="size"> /// The desired size of the image. /// </param> /// <param name="minSize"> /// Thi mimimum accetable size. /// </param> /// <returns> /// Returns an observable sequence which contains an image(s) of <paramref name="size"/> loaded using <paramref name="uri"/>. /// </returns> /// <remarks> /// If the image cannot be loaded or loaded image has smaller size than requested, then it tries to load the image using fallback /// <see cref="BaseImageLoader"/>. All intermediate images (the images of smaller size than requested), are pushed into observable sequence. /// </remarks> protected IObservable<ImageInfo> WhenLoaded(Uri uri, Size size, Size minSize) { var result = Observable.Create<ImageInfo>(observer => { ImageInfo image = null; var compositeDisposable = new CompositeDisposable(); compositeDisposable.Add(this.WhenLoadedInternal(uri, size).Subscribe( img => { observer.OnNext(img); image = img; }, err => { if (fallbackLoader != null) { compositeDisposable.Add(this.fallbackLoader.WhenLoaded(uri, size, minSize) .Do(this.OnFallbackImageLoaded) .Subscribe(observer)); } else { observer.OnError(err); } }, () => { if ((image == null || image.IsFittedIn(size) == false || image.ForceFallback) && fallbackLoader != null) { compositeDisposable.Add(this.fallbackLoader.WhenLoaded(uri, size, image == null ? minSize : image.Size) .Do(this.OnFallbackImageLoaded) .Subscribe(observer)); } else { observer.OnCompleted(); } })); return () => { compositeDisposable.Dispose(); }; }); return result; }