/* Queue.cs $ This file is part of the HandBrake source code. Homepage: . It may be used under the terms of the GNU General Public License. */ namespace HandBrake.ApplicationServices.Services { using System; using System.Diagnostics; using System.Windows.Forms; using HandBrake.ApplicationServices.EventArgs; using HandBrake.ApplicationServices.Functions; using HandBrake.ApplicationServices.Model; using HandBrake.ApplicationServices.Services.Interfaces; /// /// The HandBrake Queue /// public class QueueProcessor : IQueueProcessor { /// /// Initializes a new instance of the class. /// /// /// The queue manager. /// /// /// The encode Service. /// /// /// public QueueProcessor(IQueueManager queueManager, IEncode encodeService) { this.QueueManager = queueManager; this.EncodeService = encodeService; if (this.QueueManager == null) { throw new ArgumentNullException("queueManager"); } if (this.QueueManager == null) { throw new ArgumentNullException("queueManager"); } } /// /// Initializes a new instance of the class. /// This call also initializes the Encode and QueueManager services /// /// /// The instance id. /// public QueueProcessor(int instanceId) { this.EncodeService = new Encode(); this.QueueManager = new QueueManager(instanceId); } #region Events /// /// Queue Progess Status /// /// /// The sender. /// /// /// The QueueProgressEventArgs. /// public delegate void QueueProgressStatus(object sender, QueueProgressEventArgs e); /// /// Fires when the Queue has started /// public event QueueProgressStatus JobProcessingStarted; /// /// Fires when a pause to the encode queue has been requested. /// public event EventHandler QueuePaused; /// /// Fires when the entire encode queue has completed. /// public event EventHandler QueueCompleted; /// /// Invoke the JobProcessingStarted event /// /// /// The QueueProgressEventArgs. /// private void InvokeJobProcessingStarted(QueueProgressEventArgs e) { QueueProgressStatus handler = this.JobProcessingStarted; if (handler != null) { handler(this, e); } } /// /// Invoke the QueuePaused event /// /// /// The EventArgs. /// private void InvokeQueuePaused(EventArgs e) { EventHandler handler = this.QueuePaused; if (handler != null) { handler(this, e); } } /// /// Invoke the QueueCompleted event. /// /// /// The EventArgs. /// private void InvokeQueueCompleted(EventArgs e) { this.IsProcessing = false; EventHandler handler = this.QueueCompleted; if (handler != null) { handler(this, e); } } #endregion #region Properties /// /// Gets a value indicating whether IsProcessing. /// public bool IsProcessing { get; private set; } /// /// Gets the IEncodeService instance. /// public IEncode EncodeService { get; private set; } /// /// Gets the IQueueManager instance. /// public IQueueManager QueueManager { get; private set; } #endregion /// /// Starts encoding the first job in the queue and continues encoding until all jobs /// have been encoded. /// public void Start() { if (IsProcessing) { throw new Exception("Already Processing the Queue"); } IsProcessing = true; this.EncodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted; this.ProcessNextJob(); } /// /// Requests a pause of the encode queue. /// public void Pause() { this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted; this.InvokeQueuePaused(EventArgs.Empty); this.IsProcessing = false; } /// /// After an encode is complete, move onto the next job. /// /// /// The sender. /// /// /// The EncodeCompletedEventArgs. /// private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e) { // Growl if (Init.GrowlEncode) GrowlCommunicator.Notify("Encode Completed", "Put down that cocktail...\nyour Handbrake encode is done."); if (!e.Successful) { this.Pause(); MessageBox.Show(e.Exception + e.ErrorInformation); } // Handling Log Data this.EncodeService.ProcessLogs(this.QueueManager.LastProcessedJob.Destination); // Move onto the next job. this.ProcessNextJob(); } /// /// Run through all the jobs on the queue. /// private void ProcessNextJob() { if (this.EncodeService.IsEncoding || !this.IsProcessing) { // We don't want to try start a second encode, so just return out. The event will trigger the next encode automatically. // Also, we don't want to start a new encode if we are paused. return; } QueueTask job = this.QueueManager.GetNextJobForProcessing(); if (job != null) { this.EncodeService.Start(job, true); this.InvokeJobProcessingStarted(new QueueProgressEventArgs(job)); } else { // No more jobs to process, so unsubscribe the event this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted; // Fire the event to tell connected services. this.InvokeQueueCompleted(EventArgs.Empty); // Run the After encode completeion work Finish(); } } /// /// Perform an action after an encode. e.g a shutdown, standby, restart etc. /// private static void Finish() { // Growl if (Init.GrowlQueue) GrowlCommunicator.Notify("Queue Completed", "Put down that cocktail...\nyour Handbrake queue is done."); // Do something whent he encode ends. switch (Init.CompletionOption) { case "Shutdown": Process.Start("Shutdown", "-s -t 60"); break; case "Log off": Win32.ExitWindowsEx(0, 0); break; case "Suspend": Application.SetSuspendState(PowerState.Suspend, true, true); break; case "Hibernate": Application.SetSuspendState(PowerState.Hibernate, true, true); break; case "Lock System": Win32.LockWorkStation(); break; case "Quit HandBrake": Application.Exit(); break; default: break; } } } }