2021-08-11 20:22:36 -06:00

89 lines
2.5 KiB
C#

using Dinah.Core.Net.Http;
using Dinah.Core.Windows.Forms;
using FileLiberator;
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace LibationWinForms.BookLiberation
{
public class StreamBaseForm : Form
{
private int InstanceThreadId { get; } = Thread.CurrentThread.ManagedThreadId;
public new bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != InstanceThreadId;
private SynchronizationContext SyncContext { get; }
public StreamBaseForm()
{
//Will not work if set outside constructor.
SyncContext = SynchronizationContext.Current;
}
protected IStreamable Streamable { get; private set; }
public void SetStreamable(IStreamable streamable)
{
Streamable = streamable;
if (Streamable is null) return;
OnUnsubscribeAll(this, EventArgs.Empty);
Streamable.StreamingBegin += OnStreamingBegin;
Streamable.StreamingCompleted += OnStreamingCompleted;
Streamable.StreamingProgressChanged += OnStreamingProgressChanged;
Streamable.StreamingTimeRemaining += OnStreamingTimeRemaining;
Disposed += OnUnsubscribeAll;
}
private void OnUnsubscribeAll(object sender, EventArgs e)
{
Disposed -= OnUnsubscribeAll;
Streamable.StreamingBegin -= OnStreamingBegin;
Streamable.StreamingCompleted -= OnStreamingCompleted;
Streamable.StreamingProgressChanged -= OnStreamingProgressChanged;
Streamable.StreamingTimeRemaining -= OnStreamingTimeRemaining;
}
#region IStreamable event handlers
public virtual void OnStreamingBegin(object sender, string beginString)
{
//If StreamingBegin is fired from a worker thread, the form will be created on
//that UI thread. Form.BeginInvoke won't work until the form is created (ie. shown),
//so we need to make certain that we show the form on the same thread that created
//this StreamBaseForm.
static void sendCallback(object asyncArgs)
{
var e = asyncArgs as AsyncCompletedEventArgs;
((Action)e.UserState)();
}
Action code = Show;
if (InvokeRequired)
{
var args = new AsyncCompletedEventArgs(null, false, code);
SyncContext.Send(
sendCallback,
args);
}
else
{
code();
}
}
public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { }
public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { }
public virtual void OnStreamingCompleted(object sender, string completedString)
=> this.UIThread(() =>
{
Close();
Dispose();
});
#endregion
}
}