using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace GalaSoft.MvvmLight.Messaging
{
/// <summary>
/// Use this class to send a message when the busy state of an application changes.
/// </summary>
public class BusyMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="BusyMessage"/> class.
/// </summary>
public BusyMessage()
{
}
/// <summary>
/// Gets or sets a value indicating whether the application is currently in a busy state.
/// </summary>
public bool IsBusy { get; set; }
/// <summary>
/// Gets or sets user state information to include with the message.
/// </summary>
public object UserState { get; set; }
}
/// <summary>
/// Provides a thread-safe controller for managing the busy state of the application.
/// </summary>
public class BusyController : GalaSoft.MvvmLight.ViewModelBase
{
private readonly object syncRoot = new object();
private int count;
/// <summary>
/// Initializes static members of the <see cref="BusyController"/> class.
/// </summary>
static BusyController()
{
_default = new BusyController();
}
/// <summary>
/// Initializes a new instance of the <see cref="BusyController"/> class.
/// </summary>
public BusyController()
: base(Messenger.Default)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BusyController"/> class.
/// </summary>
/// <param name="messenger">Optional. An <see cref="IMessenger"/> which will be used to send messages.</param>
public BusyController(IMessenger messenger)
: base(messenger)
{
}
private static BusyController _default;
/// <summary>
/// Gets the default busy controller instance.
/// </summary>
public static BusyController Default
{
get
{
return _default;
}
}
private bool _isBusy;
/// <summary>
/// Gets a value indicating whether the controller is currently in the busy state.
/// </summary>
public bool IsBusy
{
get
{
return this._isBusy;
}
private set
{
if (this._isBusy != value)
{
this._isBusy = value;
this.RaisePropertyChanged(() => this.IsBusy);
}
}
}
/// <summary>
/// Resets the controller.
/// </summary>
public void Reset()
{
lock (this.syncRoot)
{
this.IsBusy = false;
this.count = 0;
if (this.MessengerInstance != null)
{
// Send the message indicating that the controller is no longer busy.
this.MessengerInstance.Send<BusyMessage>(new BusyMessage() { IsBusy = false });
}
}
}
/// <summary>
/// Sends the message
/// </summary>
/// <param name="value"><b>true</b> if the application is busy; otherwise, <b>false</b> when the application is no longer busy.</param>
/// <param name="state">Optional. User state data to include with the message if the controller transitions between busy states.</param>
public void SendMessage(bool value, object userState = null)
{
lock (this.syncRoot)
{
bool send = false;
if (value)
{
Interlocked.Increment(ref this.count);
if (this.count == 1)
{
this.IsBusy = true;
// The controller is now busy, send the message.
send = true;
}
}
else
{
if (this.count > 0)
{
Interlocked.Decrement(ref this.count);
}
if (this.count == 0)
{
this.IsBusy = false;
// The controller is no longer busy, send the message.
send = true;
}
}
if (send && this.MessengerInstance != null)
{
this.MessengerInstance.Send<BusyMessage>(new BusyMessage() { IsBusy = this.IsBusy, UserState = userState });
}
}
}
}
}