// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.ComponentModel;
using System.Threading;
namespace System.Reactive.PlatformServices
{
///
/// (Infrastructure) Provides access to local system clock services.
///
///
/// This type is used by the Rx infrastructure and not meant for public consumption or implementation.
/// No guarantees are made about forward compatibility of the type's functionality and its usage.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public static class SystemClock
{
private static Lazy s_serviceSystemClock = new Lazy(InitializeSystemClock);
private static Lazy s_serviceSystemClockChanged = new Lazy(InitializeSystemClockChanged);
private static int _refCount;
///
/// Gets the local system clock time.
///
public static DateTimeOffset UtcNow
{
get { return s_serviceSystemClock.Value.UtcNow; }
}
///
/// Event that gets raised when a system clock change is detected, if there's any interest as indicated by AddRef calls.
///
public static event EventHandler SystemClockChanged;
///
/// Adds a reference to the system clock monitor, causing it to be sending notifications.
///
/// Thrown when the system doesn't support sending clock change notifications.
public static void AddRef()
{
if (Interlocked.Increment(ref _refCount) == 1)
{
s_serviceSystemClockChanged.Value.SystemClockChanged += OnSystemClockChanged;
}
}
///
/// Removes a reference to the system clock monitor, causing it to stop sending notifications
/// if the removed reference was the last one.
///
public static void Release()
{
if (Interlocked.Decrement(ref _refCount) == 0)
{
s_serviceSystemClockChanged.Value.SystemClockChanged -= OnSystemClockChanged;
}
}
private static void OnSystemClockChanged(object sender, SystemClockChangedEventArgs e)
{
var scc = SystemClockChanged;
if (scc != null)
scc(sender, e);
}
private static ISystemClock InitializeSystemClock()
{
return PlatformEnlightenmentProvider.Current.GetService() ?? new DefaultSystemClock();
}
private static INotifySystemClockChanged InitializeSystemClockChanged()
{
return PlatformEnlightenmentProvider.Current.GetService() ?? new DefaultSystemClockMonitor();
}
}
///
/// (Infrastructure) Provides access to the local system clock.
///
///
/// This type is used by the Rx infrastructure and not meant for public consumption or implementation.
/// No guarantees are made about forward compatibility of the type's functionality and its usage.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public interface ISystemClock
{
///
/// Gets the current time.
///
DateTimeOffset UtcNow { get; }
}
///
/// (Infrastructure) Provides a mechanism to notify local schedulers about system clock changes.
///
///
/// This type is used by the Rx infrastructure and not meant for public consumption or implementation.
/// No guarantees are made about forward compatibility of the type's functionality and its usage.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public interface INotifySystemClockChanged
{
///
/// Event that gets raised when a system clock change is detected.
///
event EventHandler SystemClockChanged;
}
///
/// (Infrastructure) Event arguments for system clock change notifications.
///
///
/// This type is used by the Rx infrastructure and not meant for public consumption or implementation.
/// No guarantees are made about forward compatibility of the type's functionality and its usage.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public class SystemClockChangedEventArgs : EventArgs
{
///
/// Creates a new system clock notification object with unknown old and new times.
///
public SystemClockChangedEventArgs()
: this(DateTimeOffset.MinValue, DateTimeOffset.MaxValue)
{
}
///
/// Creates a new system clock notification object with the specified old and new times.
///
/// Time before the system clock changed, or DateTimeOffset.MinValue if not known.
/// Time after the system clock changed, or DateTimeOffset.MaxValue if not known.
public SystemClockChangedEventArgs(DateTimeOffset oldTime, DateTimeOffset newTime)
{
OldTime = oldTime;
NewTime = newTime;
}
///
/// Gets the time before the system clock changed, or DateTimeOffset.MinValue if not known.
///
public DateTimeOffset OldTime { get; private set; }
///
/// Gets the time after the system clock changed, or DateTimeOffset.MaxValue if not known.
///
public DateTimeOffset NewTime { get; private set; }
}
}