// 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; } } }