Beispiel #1
0
        private void ProcessPanelQueue()
        {
            this.logger.Verbose("In ProcessPanelQueue...");

            this.LogInfo();

            // sanity check: it's possible that the timer has been paused.  we will short circuit here.
            if (!this.timer.IsEnabled)
            {
                this.logger.Info("Timer is paused, exiting ProcessPanelQueue");
                return;
            }

            // pickup and new panels and add them to the queue.
            // only add panels not already in the queue
            this.PanelsDue().ForEach(p => this.panelCaptureQueue.Enqueue(p));

            if (!this.panelCaptureQueue.Any())
            {
                this.logger.Verbose("ProcessPanelQueue - No panels to process.");
                return;
            }

            if (this.currentCapture != null)
            {
                this.logger.Warn("Cannot Process more queue items, currently waiting on {0}", this.currentCapture.Config.PrettyName);
                return;
            }

            this.logger.Info("Processing {0} panels", this.panelCaptureQueue.Count());

            // take the first item and begin processing that, we will chain the processing
            // when this panel completes or fails we will receive notification and will move
            // on to the next panel.

            // NOTE: why we chain - we need to serialize these due to the way we take the screen-shot.
            // currently I don't have a way to ask the WebView to capture itself, I need
            // to actually capture the screen.  This has it's drawbacks as any other app windows
            // overlay-ed on top of our WebView will be captured.
            if (this.panelCaptureQueue.TryDequeue(out ScreenCapturePanel nextPanel))
            {
                this.logger.Info("Dequeued {0}", nextPanel.Config.PrettyName);

                // we use the current capture as a sanity check to ensure we don't process this again
                // in addition to checking if the panel itself thinks it is capturing.
                this.currentCapture = nextPanel;

                // panels will call back to this ProcessPanelQueue when they are done processing work.
                // this will allow the queue to continue to drain.
                // this is an async operation...
                nextPanel.CaptureScreen(this);
            }

            this.LogInfo();

            this.logger.Info("Exiting ProcessPanelQueue.");
        }
Beispiel #2
0
        public void NotifyPanelProcessingComplete(ScreenCapturePanel panel)
        {
            this.logger.Info("Receiving completion notification from panel: {0}", panel.Config.PrettyName);

            if (this.currentCapture == panel)
            {
                this.currentCapture = null;
            }

            this.NotifyPanelProcessingCompleteHandler?.Invoke();

            this.ProcessPanelQueue();
        }
Beispiel #3
0
        public void SetPanels(ScreenCapturePanel[] panels)
        {
            this.panelsToCapture = panels;

            // it's possible that old panels were in the queue but were removed during a recycle, we'll
            // add the new versions back into the queue.  the ControllerService can be a caller to SetPanels which
            // is how we would get in this state where the queue had old panels in it.
            var queueSnapshot = this.panelCaptureQueue.ToList();

            this.panelCaptureQueue.Clear();

            // compute the min interval
            var minimumInterval = this.panelsToCapture
                                  .Select(panel => panel.Config.Interval)
                                  .DefaultIfEmpty(TimeSpan.Zero)
                                  .Min();

            this.timer.Interval = minimumInterval;

            if (minimumInterval == TimeSpan.Zero)
            {
                this.logger.Warn("TimedCaptureService: timer interval set to Zero, stopping timer");
                this.timer.Stop();
            }

            if (queueSnapshot.Any())
            {
                this.logger.Warn("There were items in the queue while SetPanels was being called.  Will enqueue new panels for these items");
                queueSnapshot.ForEach(oldPanel =>
                {
                    // probably not the most accurate way to do this, we could also just check the config pointer.
                    // the assumption here is that the new panel list will always have a match for an old queued item
                    // if we do not find a match then that queued item will not get run as we have already cleared it from
                    // the queue.
                    var match = this.panelsToCapture.FirstOrDefault(p => p.Config.Name == oldPanel.Config.Name);

                    if (match != null)
                    {
                        logger.Info($"Enqueuing new panel replacement for existing queue item: '{oldPanel.Config.PrettyName}'");
                        this.panelCaptureQueue.Enqueue(match);
                    }
                    else
                    {
                        this.logger.Warn($"Cannot find new panel for old panel in queue with name '{oldPanel.Config.PrettyName}, old queued item has been dropped'");
                    }
                });
            }

            // there could be something processing and now that panel has gone away.  lets just clear the current processing
            // panel prop
            if (this.currentCapture != null &&
                this.panelsToCapture.FirstOrDefault(p => p == this.currentCapture) == null)
            {
                // it's possible with the recycle panels caller we could get into this state.
                // if the user is adding a new panel then we shuldn't get here.
                this.logger.Warn("clearing currentCapture, there is no matching panel after set panels");
                this.currentCapture = null;
            }

            this.LogInfo();
        }