summaryrefslogtreecommitdiffstats
path: root/win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs
diff options
context:
space:
mode:
authorsr55 <[email protected]>2011-01-09 14:37:29 +0000
committersr55 <[email protected]>2011-01-09 14:37:29 +0000
commit49c029031755e78e10cc4c0d004dc93d42714566 (patch)
treea1d88a51560ea03fdf03dd3da1179b95436f4365 /win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs
parent9f60eb35c21d513c6ce6b272e371a279b8a32ae5 (diff)
WinGui:
- Continuing on with the Application Services re-factoring: * Added new QueueManager - Manages queue jobs, add, remove, up, down, save, etc * Queue Processor - Processes a Queue * New Models (Encode Task + associated model objects) Used for storing jobs as an object rather than query. This code isn't used yet, that is coming later. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3738 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs')
-rw-r--r--win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs338
1 files changed, 338 insertions, 0 deletions
diff --git a/win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs b/win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs
new file mode 100644
index 000000000..05602f13d
--- /dev/null
+++ b/win/C#/HandBrake.ApplicationServices/Services/QueueManager.cs
@@ -0,0 +1,338 @@
+namespace HandBrake.ApplicationServices.Services
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.IO;
+ using System.Linq;
+ using System.Windows.Forms;
+ using System.Xml.Serialization;
+
+ using HandBrake.ApplicationServices.Model;
+ using HandBrake.ApplicationServices.Services.Interfaces;
+
+ using EventArgs = System.EventArgs;
+
+ /// <summary>
+ /// The Queue Manager.
+ /// Thread Safe.
+ /// </summary>
+ public class QueueManager : IQueueManager
+ {
+ /*
+ * TODO
+ * - Multi HandBrake Instance Support for Queue Saving.
+ * - Rewrite the batch script generator.
+ */
+
+ #region Private Variables
+
+ /// <summary>
+ /// HandBrakes Queue file with a place holder for an extra string.
+ /// Use this with String.Format()
+ /// </summary>
+ private const string QueueFile = "hb_queue_recovery{0}.xml";
+
+ /// <summary>
+ /// A Lock object to maintain thread safety
+ /// </summary>
+ static readonly object QueueLock = new object();
+
+ /// <summary>
+ /// The Queue of Job objects
+ /// </summary>
+ private readonly List<QueueTask> queue = new List<QueueTask>();
+
+ /// <summary>
+ /// The ID of the job last added
+ /// </summary>
+ private int lastJobId;
+
+ /// <summary>
+ /// The instance Id of this HandBrake instance.
+ /// </summary>
+ private int instanceId;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QueueManager"/> class.
+ /// </summary>
+ /// <param name="instanceId">
+ /// The instance Id.
+ /// </param>
+ public QueueManager(int instanceId)
+ {
+ this.instanceId = instanceId;
+ }
+
+ #region Events
+ /// <summary>
+ /// Fires when a job is Added, Removed or Re-Ordered.
+ /// Should be used for triggering an update of the Queue Window.
+ /// </summary>
+ public event EventHandler QueueChanged;
+
+ /// <summary>
+ /// Invoke the Queue Changed Event
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void InvokeQueueChanged(EventArgs e)
+ {
+ try
+ {
+ this.BackupQueue(string.Empty);
+ }
+ catch (Exception)
+ {
+ // Do Nothing.
+ }
+
+ EventHandler handler = this.QueueChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets or sets Last Processed Job.
+ /// This is set when the job is poped of the queue by GetNextJobForProcessing();
+ /// </summary>
+ public QueueTask LastProcessedJob { get; set; }
+
+ /// <summary>
+ /// Gets the number of jobs in the queue;
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ return this.queue.Count;
+ }
+ }
+
+ /// <summary>
+ /// Gets The current queue.
+ /// </summary>
+ public ReadOnlyCollection<QueueTask> Queue
+ {
+ get
+ {
+ return this.queue.AsReadOnly();
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Add a job to the Queue.
+ /// This method is Thread Safe.
+ /// </summary>
+ /// <param name="job">
+ /// The encode Job object.
+ /// </param>
+ public void Add(QueueTask job)
+ {
+ lock (QueueLock)
+ {
+ // Tag the job with an ID
+ job.Id = lastJobId++;
+ queue.Add(job);
+ InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Remove a job from the Queue.
+ /// This method is Thread Safe
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ public void Remove(QueueTask job)
+ {
+ lock (QueueLock)
+ {
+ // Tag the job with an ID
+ job.Id = lastJobId++;
+ queue.Add(job);
+ InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Get the first job on the queue for processing.
+ /// This also removes the job from the Queue and sets the LastProcessedJob
+ /// </summary>
+ /// <returns>
+ /// An encode Job object.
+ /// </returns>
+ public QueueTask GetNextJobForProcessing()
+ {
+ if (this.queue.Count > 0)
+ {
+ QueueTask job = this.queue[0];
+ this.LastProcessedJob = job;
+ this.Remove(job); // Remove the item which we are about to pass out.
+
+ return job;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Moves an item up one position in the queue.
+ /// </summary>
+ /// <param name="index">The zero-based location of the job in the queue.</param>
+ public void MoveUp(int index)
+ {
+ if (index > 0)
+ {
+ QueueTask item = queue[index];
+
+ queue.RemoveAt(index);
+ queue.Insert((index - 1), item);
+ }
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Moves an item down one position in the queue.
+ /// </summary>
+ /// <param name="index">The zero-based location of the job in the queue.</param>
+ public void MoveDown(int index)
+ {
+ if (index < this.queue.Count - 1)
+ {
+ QueueTask item = this.queue[index];
+
+ this.queue.RemoveAt(index);
+ this.queue.Insert((index + 1), item);
+ }
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Backup any changes to the queue file
+ /// </summary>
+ /// <param name="exportPath">
+ /// If this is not null or empty, this will be used instead of the standard backup location.
+ /// </param>
+ public void BackupQueue(string exportPath)
+ {
+ string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
+ string tempPath = !string.IsNullOrEmpty(exportPath) ? exportPath : appDataPath + string.Format(QueueFile, string.Empty);
+
+ if (File.Exists(tempPath))
+ {
+ using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));
+ serializer.Serialize(strm, queue);
+ strm.Close();
+ strm.Dispose();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Restore a Queue from file or from the queue backup file.
+ /// </summary>
+ /// <param name="importPath">
+ /// The import path. String.Empty or null will result in the default file being loaded.
+ /// </param>
+ public void RestoreQueue(string importPath)
+ {
+ string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
+ string tempPath = !string.IsNullOrEmpty(importPath) ? importPath : (appDataPath + string.Format(QueueFile, string.Empty));
+
+ if (File.Exists(tempPath))
+ {
+ using (FileStream strm = new FileStream((!string.IsNullOrEmpty(importPath) ? importPath : tempPath), FileMode.Open, FileAccess.Read))
+ {
+ if (strm.Length != 0)
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));
+
+ List<QueueTask> list = serializer.Deserialize(strm) as List<QueueTask>;
+
+ if (list != null)
+ foreach (QueueTask item in list)
+ this.queue.Add(item);
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks the current queue for an existing instance of the specified destination.
+ /// </summary>
+ /// <param name="destination">The destination of the encode.</param>
+ /// <returns>Whether or not the supplied destination is already in the queue.</returns>
+ public bool CheckForDestinationPathDuplicates(string destination)
+ {
+ return this.queue.Any(checkItem => checkItem.Task.Destination.Contains(destination.Replace("\\\\", "\\")));
+ }
+
+ /// <summary>
+ /// Writes the current state of the queue in the form of a batch (.bat) file.
+ /// </summary>
+ /// <param name="file">
+ /// The location of the file to write the batch file to.
+ /// </param>
+ /// <returns>
+ /// The write batch script to file.
+ /// </returns>
+ public bool WriteBatchScriptToFile(string file)
+ {
+ string queries = string.Empty;
+ foreach (QueueTask queueItem in this.queue)
+ {
+ string qItem = queueItem.Query;
+ string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + qItem;
+
+ if (queries == string.Empty)
+ queries = queries + fullQuery;
+ else
+ queries = queries + " && " + fullQuery;
+ }
+ string strCmdLine = queries;
+
+ if (file != string.Empty)
+ {
+ try
+ {
+ // Create a StreamWriter and open the file, Write the batch file query to the file and
+ // Close the stream
+ using (StreamWriter line = new StreamWriter(file))
+ {
+ line.WriteLine(strCmdLine);
+ }
+
+ return true;
+ }
+ catch (Exception exc)
+ {
+ throw new Exception("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", exc);
+ }
+ }
+ return false;
+ }
+
+ #endregion
+ }
+}