private void SubscribeTaskForRequestCancellation(
     AtomicBoolean isCancelled,
     IProducerContext producerContext)
 {
     producerContext.AddCallbacks(
         new BaseProducerContextCallbacks(
             () =>
     {
         isCancelled.Value = true;
     },
             () => { },
             () => { },
             () => { }));
 }
        /// <summary>
        /// Start producing results for given context.
        /// Provided consumer is notified whenever progress is made
        /// (new value is ready or error occurs).
        /// </summary>
        public void ProduceResults(
            IConsumer <EncodedImage> consumer,
            IProducerContext producerContext)
        {
            IProducerListener listener     = producerContext.Listener;
            string            requestId    = producerContext.Id;
            ImageRequest      imageRequest = producerContext.ImageRequest;
            StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable =
                new StatefulProducerRunnableImpl <EncodedImage>(
                    consumer,
                    listener,
                    ProducerName,
                    requestId,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    (result) =>
            {
                EncodedImage.CloseSafely(result);
            },
                    async() =>
            {
                EncodedImage encodedImage = await GetEncodedImage(imageRequest)
                                            .ConfigureAwait(false);

                if (encodedImage == null)
                {
                    return(null);
                }

                await encodedImage.ParseMetaDataAsync().ConfigureAwait(false);
                return(encodedImage);
            });

            producerContext.AddCallbacks(
                new BaseProducerContextCallbacks(
                    () =>
            {
                cancellableProducerRunnable.Cancel();
            },
                    () => { },
                    () => { },
                    () => { }));

            _executor.Execute(cancellableProducerRunnable.Runnable);
        }
            /// <summary>
            /// Instantiates the <see cref="ProgressiveDecoder"/>.
            /// </summary>
            public ProgressiveDecoder(
                DecodeProducer parent,
                IConsumer <CloseableReference <CloseableImage> > consumer,
                IProducerContext producerContext) :
                base(consumer)
            {
                _parent             = parent;
                _producerContext    = producerContext;
                _producerListener   = producerContext.Listener;
                _imageDecodeOptions = producerContext.ImageRequest.ImageDecodeOptions;
                _isFinished         = false;
                Func <EncodedImage, bool, Task> job = (encodedImage, isLast) =>
                {
                    if (encodedImage != null)
                    {
                        if (_parent._downsampleEnabled)
                        {
                            ImageRequest request = producerContext.ImageRequest;
                            if (_parent._downsampleEnabledForNetwork ||
                                !UriUtil.IsNetworkUri(request.SourceUri))
                            {
                                encodedImage.SampleSize = DownsampleUtil.DetermineSampleSize(
                                    request, encodedImage);
                            }
                        }

                        return(DoDecode(encodedImage, isLast));
                    }

                    return(Task.CompletedTask);
                };

                _jobScheduler = new JobScheduler(
                    _parent._executor, job, _imageDecodeOptions.MinDecodeIntervalMs);

                _producerContext.AddCallbacks(
                    new BaseProducerContextCallbacks(
                        () => { },
                        () => { },
                        () =>
                {
                    if (_producerContext.IsIntermediateResultExpected)
                    {
                        _jobScheduler.ScheduleJob();
                    }
                },
                        () => { }));
            }
        /// <summary>
        /// Start producing results for given context.
        /// Provided consumer is notified whenever progress is made
        /// (new value is ready or error occurs).
        /// </summary>

        public void ProduceResults(IConsumer <T> consumer, IProducerContext context)
        {
            IProducerListener            producerListener = context.Listener;
            string                       requestId        = context.Id;
            StatefulProducerRunnable <T> statefulRunnable = new StatefulProducerRunnableImpl <T>(
                consumer,
                producerListener,
                PRODUCER_NAME,
                requestId,
                (T ignored) =>
            {
                producerListener.OnProducerFinishWithSuccess(requestId, PRODUCER_NAME, null);
                _inputProducer.ProduceResults(consumer, context);
            },
                null,
                null,
                (_) =>
            {
                return(default(IDictionary <string, string>));
            },
                (_) =>
            {
                return(default(IDictionary <string, string>));
            },
                () =>
            {
                return(default(IDictionary <string, string>));
            },
                null,
                () =>
            {
                return(Task.FromResult(default(T)));
            });

            context.AddCallbacks(
                new BaseProducerContextCallbacks(
                    () =>
            {
                statefulRunnable.Cancel();
                _threadHandoffProducerQueue.Remove(statefulRunnable.Runnable);
            },
                    () => { },
                    () => { },
                    () => { }));

            _threadHandoffProducerQueue.AddToQueueOrExecute(statefulRunnable.Runnable);
        }
Ejemplo n.º 5
0
 internal RepeatedPostprocessorConsumer(
     PostprocessorConsumer postprocessorConsumer,
     IRepeatedPostprocessor repeatedPostprocessor,
     IProducerContext context) :
     base(postprocessorConsumer)
 {
     repeatedPostprocessor.SetCallback(this);
     context.AddCallbacks(
         new BaseProducerContextCallbacks(
             () =>
     {
         if (Close())
         {
             Consumer.OnCancellation();
         }
     },
             () => { },
             () => { },
             () => { }));
 }
Ejemplo n.º 6
0
            /// <summary>
            /// Instantiates the <see cref="TransformingConsumer"/>.
            /// </summary>
            public TransformingConsumer(
                ResizeAndRotateProducer parent,
                IConsumer <EncodedImage> consumer,
                IProducerContext producerContext) :
                base(consumer)
            {
                _parent          = parent;
                _isCancelled     = false;
                _producerContext = producerContext;

                Func <EncodedImage, bool, Task> job = (encodedImage, isLast) =>
                {
                    return(DoTransform(encodedImage, isLast));
                };

                _jobScheduler = new JobScheduler(
                    _parent._executor, job, MIN_TRANSFORM_INTERVAL_MS);

                _producerContext.AddCallbacks(
                    new BaseProducerContextCallbacks(
                        () =>
                {
                    _jobScheduler.ClearJob();
                    _isCancelled = true;

                    // This only works if it is safe to discard the output of
                    // previous producer
                    consumer.OnCancellation();
                },
                        () => { },
                        () =>
                {
                    if (_producerContext.IsIntermediateResultExpected)
                    {
                        _jobScheduler.ScheduleJob();
                    }
                },
                        () => {
                }));
            }
Ejemplo n.º 7
0
 internal PostprocessorConsumer(
     PostprocessorProducer parent,
     IConsumer <CloseableReference <CloseableImage> > consumer,
     IProducerListener listener,
     string requestId,
     IPostprocessor postprocessor,
     IProducerContext producerContext) :
     base(consumer)
 {
     _parent        = parent;
     _listener      = listener;
     _requestId     = requestId;
     _postprocessor = postprocessor;
     producerContext.AddCallbacks(
         new BaseProducerContextCallbacks(
             () =>
     {
         MaybeNotifyOnCancellation();
     },
             () => { },
             () => { },
             () => { }));
 }
Ejemplo n.º 8
0
            /// <summary>
            /// Register callbacks to be called when cancellation of consumer
            /// is requested, or if the prefetch status of the consumer changes.
            /// </summary>
            private void AddCallbacks(
                Tuple <IConsumer <T>, IProducerContext> consumerContextPair,
                IProducerContext producerContext)
            {
                producerContext.AddCallbacks(
                    new BaseProducerContextCallbacks(
                        () =>
                {
                    BaseProducerContext contextToCancel = null;
                    IList <IProducerContextCallbacks> isPrefetchCallbacks = null;
                    IList <IProducerContextCallbacks> priorityCallbacks   = null;
                    IList <IProducerContextCallbacks> isIntermediateResultExpectedCallbacks = null;
                    bool pairWasRemoved = false;

                    lock (_gate)
                    {
                        object val     = default(object);
                        pairWasRemoved = _consumerContextPairs.TryRemove(consumerContextPair, out val);
                        if (pairWasRemoved)
                        {
                            if (_consumerContextPairs.IsEmpty)
                            {
                                contextToCancel = _multiplexProducerContext;
                            }
                            else
                            {
                                isPrefetchCallbacks = UpdateIsPrefetch();
                                priorityCallbacks   = UpdatePriority();
                                isIntermediateResultExpectedCallbacks = UpdateIsIntermediateResultExpected();
                            }
                        }
                    }

                    BaseProducerContext.CallOnIsPrefetchChanged(isPrefetchCallbacks);
                    BaseProducerContext.CallOnPriorityChanged(priorityCallbacks);
                    BaseProducerContext.CallOnIsIntermediateResultExpectedChanged(
                        isIntermediateResultExpectedCallbacks);

                    if (contextToCancel != null)
                    {
                        contextToCancel.Cancel();
                    }

                    if (pairWasRemoved)
                    {
                        consumerContextPair.Item1.OnCancellation();
                    }
                },
                        () =>
                {
                    BaseProducerContext.CallOnIsPrefetchChanged(UpdateIsPrefetch());
                },
                        () =>
                {
                    BaseProducerContext.CallOnIsIntermediateResultExpectedChanged(
                        UpdateIsIntermediateResultExpected());
                },
                        () =>
                {
                    BaseProducerContext.CallOnPriorityChanged(UpdatePriority());
                }));
            }
        /// <summary>
        /// Start producing results for given context.
        /// Provided consumer is notified whenever progress is made
        /// (new value is ready or error occurs).
        /// </summary>
        public void ProduceResults(
            IConsumer <EncodedImage> consumer,
            IProducerContext producerContext)
        {
            IProducerListener listener     = producerContext.Listener;
            string            requestId    = producerContext.Id;
            ImageRequest      imageRequest = producerContext.ImageRequest;

            StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable =
                new StatefulProducerRunnableImpl <EncodedImage>(
                    consumer,
                    listener,
                    PRODUCER_NAME,
                    requestId,
                    null,
                    null,
                    null,
                    (result) =>
            {
                IDictionary <string, string> extraMap = new Dictionary <string, string>()
                {
                    { CREATED_THUMBNAIL, (result != null).ToString() }
                };

                return(new ReadOnlyDictionary <string, string>(extraMap));
            },
                    null,
                    null,
                    (result) =>
            {
                EncodedImage.CloseSafely(result);
            },
                    async() =>
            {
                Uri sourceUri    = imageRequest.SourceUri;
                StorageFile file = await StorageFile
                                   .GetFileFromApplicationUriAsync(sourceUri)
                                   .AsTask()
                                   .ConfigureAwait(false);

                using (var fileStream = await file.OpenReadAsync().AsTask().ConfigureAwait(false))
                {
                    byte[] bytes = await BitmapUtil
                                   .GetThumbnailAsync(fileStream)
                                   .ConfigureAwait(false);

                    if (bytes != null)
                    {
                        IPooledByteBuffer pooledByteBuffer =
                            _pooledByteBufferFactory.NewByteBuffer(bytes);

                        return(await BuildEncodedImage(pooledByteBuffer, fileStream)
                               .ConfigureAwait(false));
                    }
                    else
                    {
                        return(null);
                    }
                }
            });

            producerContext.AddCallbacks(
                new BaseProducerContextCallbacks(
                    () =>
            {
                cancellableProducerRunnable.Cancel();
            },
                    () => { },
                    () => { },
                    () => { }));

            _executor.Execute(cancellableProducerRunnable.Runnable);
        }