diff --git a/Perspex.Animation/Animatable.cs b/Perspex.Animation/Animatable.cs index ae5cd56604..bff50a2e46 100644 --- a/Perspex.Animation/Animatable.cs +++ b/Perspex.Animation/Animatable.cs @@ -7,7 +7,6 @@ namespace Perspex.Animation { using System.Linq; - using System.Reactive.Linq; /// /// Base class for control which can have property transitions. diff --git a/Perspex.Application/Application.cs b/Perspex.Application/Application.cs index 06980a4e24..1b94ecaa51 100644 --- a/Perspex.Application/Application.cs +++ b/Perspex.Application/Application.cs @@ -28,6 +28,8 @@ namespace Perspex /// - A global set of . /// - A . /// - An . + /// - Loads and initializes rendering and windowing subsystems with + /// and . /// - Registers services needed by the rest of Perspex in the /// method. /// - Tracks the lifetime of the application. diff --git a/Perspex.Base/Collections/PerspexListExtensions.cs b/Perspex.Base/Collections/PerspexListExtensions.cs index 8aaa32a720..331370091e 100644 --- a/Perspex.Base/Collections/PerspexListExtensions.cs +++ b/Perspex.Base/Collections/PerspexListExtensions.cs @@ -12,8 +12,25 @@ namespace Perspex.Collections using System.ComponentModel; using System.Reactive.Disposables; + /// + /// Defines extension methods for working with s. + /// public static class PerspexListExtensions { + /// + /// Invokes an action for each item in a collection and subsequently each item added or + /// removed from the collection. + /// + /// The type of the collection items. + /// The collection. + /// + /// An action called initially for each item in the collection and subsequently for each + /// item added to the collection. + /// + /// + /// An action called for each item removed from the collection. + /// + /// A disposable used to terminate the subscription. public static IDisposable ForEachItem( this IPerspexReadOnlyList collection, Action added, @@ -64,6 +81,13 @@ namespace Perspex.Collections return Disposable.Create(() => collection.CollectionChanged -= handler); } + /// + /// Listens for property changed events from all items in a collection. + /// + /// The type of the collection items. + /// The collection. + /// A callback to call for each property changed event. + /// A disposable used to terminate the subscription. public static IDisposable TrackItemPropertyChanged( this IPerspexReadOnlyList collection, Action> callback) diff --git a/Perspex.Base/Diagnostics/PerspexObjectExtensions.cs b/Perspex.Base/Diagnostics/PerspexObjectExtensions.cs index 7e644f7ebf..2f59749794 100644 --- a/Perspex.Base/Diagnostics/PerspexObjectExtensions.cs +++ b/Perspex.Base/Diagnostics/PerspexObjectExtensions.cs @@ -6,8 +6,20 @@ namespace Perspex.Diagnostics { + /// + /// Defines diagnostic extensions on s. + /// public static class PerspexObjectExtensions { + /// + /// Gets a diagnostic for a on a . + /// + /// The object. + /// The property. + /// + /// A that can be used to diagnose the state of the + /// property on the object. + /// public static PerspexPropertyValue GetDiagnostic(this PerspexObject o, PerspexProperty property) { var set = o.GetSetValues(); diff --git a/Perspex.Base/Diagnostics/PerspexPropertyValue.cs b/Perspex.Base/Diagnostics/PerspexPropertyValue.cs index ced24be77b..ada68a1d34 100644 --- a/Perspex.Base/Diagnostics/PerspexPropertyValue.cs +++ b/Perspex.Base/Diagnostics/PerspexPropertyValue.cs @@ -6,8 +6,19 @@ namespace Perspex.Diagnostics { + /// + /// Holds diagnostic-related information about the value of a + /// on a . + /// public class PerspexPropertyValue { + /// + /// Initializes a new instance of the class. + /// + /// The property. + /// The current property value. + /// The priority of the current value. + /// A diagnostic string. public PerspexPropertyValue( PerspexProperty property, object value, @@ -20,12 +31,24 @@ namespace Perspex.Diagnostics this.Diagnostic = diagnostic; } + /// + /// Gets the property. + /// public PerspexProperty Property { get; } + /// + /// Gets the current property value. + /// public object Value { get; } + /// + /// Gets the priority of the current value. + /// public BindingPriority Priority { get; } + /// + /// Gets a diagnostic string. + /// public string Diagnostic { get; } } } diff --git a/Perspex.Base/PriorityValue.cs b/Perspex.Base/PriorityValue.cs index 06d27629c6..b7a808cdc5 100644 --- a/Perspex.Base/PriorityValue.cs +++ b/Perspex.Base/PriorityValue.cs @@ -10,7 +10,6 @@ namespace Perspex using System.Collections.Generic; using System.Linq; using System.Reactive.Subjects; - using System.Reflection; using System.Text; using Perspex.Utilities; diff --git a/Perspex.Base/Threading/Dispatcher.cs b/Perspex.Base/Threading/Dispatcher.cs index b3a7c1d7ea..665a7c753e 100644 --- a/Perspex.Base/Threading/Dispatcher.cs +++ b/Perspex.Base/Threading/Dispatcher.cs @@ -11,26 +11,51 @@ namespace Perspex.Threading using System.Threading.Tasks; using Perspex.Win32.Threading; + /// + /// Provides services for managing work items on a thread. + /// + /// + /// In Perspex, there is usually only a single in the application - + /// the one for the UI thread, retrieved via the property. + /// public class Dispatcher { private static Dispatcher instance = new Dispatcher(); private MainLoop mainLoop = new MainLoop(); + /// + /// Initializes a new instance of the class. + /// private Dispatcher() { } + /// + /// Gets the for the UI thread. + /// public static Dispatcher UIThread { get { return instance; } } + /// + /// Runs the dispatcher's main loop. + /// + /// + /// A cancellation token used to exit the main loop. + /// public void MainLoop(CancellationToken cancellationToken) { this.mainLoop.Run(cancellationToken); } + /// + /// Invokes a method on the dispatcher thread. + /// + /// The method. + /// The priority with which to invoke the method. + /// A task that can be used to track the method's execution. public Task InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal) { return this.mainLoop.InvokeAsync(action, priority); diff --git a/Perspex.Base/Threading/DispatcherPriority.cs b/Perspex.Base/Threading/DispatcherPriority.cs index 00fb1df484..b8fbf84c26 100644 --- a/Perspex.Base/Threading/DispatcherPriority.cs +++ b/Perspex.Base/Threading/DispatcherPriority.cs @@ -6,19 +6,65 @@ namespace Perspex.Threading { + /// + /// Defines the priorities with which jobs can be invoked on a . + /// + // TODO: These are copied from WPF - many won't apply to Perspex. public enum DispatcherPriority { - Invalid = -1, + /// + /// The job will not be processed. + /// Inactive = 0, + + /// + /// The job will be processed when the system is idle. + /// SystemIdle = 1, + + /// + /// The job will be processed when the application sis idle. + /// ApplicationIdle = 2, + + /// + /// The job will be processed after background operations have completed. + /// ContextIdle = 3, + + /// + /// The job will be processed after other non-idle operations have completed. + /// Background = 4, + + /// + /// The job will be processed with the same priority as input. + /// Input = 5, + + /// + /// The job will be processed after layout and render but before input. + /// Loaded = 6, + + /// + /// The job will be processed with the same priority as render. + /// Render = 7, + + /// + /// The job will be processed with the same priority as data binding. + /// DataBind = 8, + + /// + /// The job will be processed with normal priority. + /// Normal = 9, + + /// + /// The job will be processed before other asynchronous operations. + /// Send = 10, } } diff --git a/Perspex.Base/Threading/DispatcherTimer.cs b/Perspex.Base/Threading/DispatcherTimer.cs index ed14b3499a..78a0e4083e 100644 --- a/Perspex.Base/Threading/DispatcherTimer.cs +++ b/Perspex.Base/Threading/DispatcherTimer.cs @@ -11,6 +11,9 @@ namespace Perspex.Threading using Perspex.Platform; using Splat; + /// + /// A timer that uses a to fire at a specified interval. + /// public class DispatcherTimer { private IDisposable timer; @@ -19,24 +22,43 @@ namespace Perspex.Threading private TimeSpan interval; + /// + /// Initializes a new instance of the class. + /// public DispatcherTimer() { this.priority = DispatcherPriority.Normal; this.Dispatcher = Dispatcher.UIThread; } + /// + /// Initializes a new instance of the class. + /// + /// The priority to use. public DispatcherTimer(DispatcherPriority priority) { this.priority = priority; this.Dispatcher = Dispatcher.UIThread; } + /// + /// Initializes a new instance of the class. + /// + /// The priority to use. + /// The dispatcher to use. public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher) { this.priority = priority; this.Dispatcher = dispatcher; } + /// + /// Initializes a new instance of the class. + /// + /// The interval at which to tick. + /// The priority to use. + /// The dispatcher to use. + /// The event to call when the timer ticks. public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher) { this.priority = priority; @@ -45,6 +67,9 @@ namespace Perspex.Threading this.Tick += callback; } + /// + /// Finalizes an instance of the class. + /// ~DispatcherTimer() { if (this.timer != null) @@ -53,14 +78,23 @@ namespace Perspex.Threading } } + /// + /// Raised when the timer ticks. + /// public event EventHandler Tick; + /// + /// Gets the dispatcher that the timer uses. + /// public Dispatcher Dispatcher { get; private set; } + /// + /// Gets or sets the interval at which the timer ticks. + /// public TimeSpan Interval { get @@ -77,6 +111,9 @@ namespace Perspex.Threading } } + /// + /// Gets or sets a value indicating whether the timer is running. + /// public bool IsEnabled { get @@ -100,12 +137,24 @@ namespace Perspex.Threading } } + /// + /// Gets or sets user-defined data associated with the timer. + /// public object Tag { get; set; } + /// + /// Starts a new timer. + /// + /// + /// The method to call on timer tick. If the method returns false, the timer will stop. + /// + /// The interval at which to tick. + /// The priority to use. + /// An used to cancel the timer. public static IDisposable Run(Func action, TimeSpan interval, DispatcherPriority priority = DispatcherPriority.Normal) { var timer = new DispatcherTimer(priority); @@ -124,6 +173,9 @@ namespace Perspex.Threading return Disposable.Create(() => timer.Stop()); } + /// + /// Starts the timer. + /// public void Start() { if (!this.IsEnabled) @@ -133,6 +185,9 @@ namespace Perspex.Threading } } + /// + /// Stops the timer. + /// public void Stop() { if (this.IsEnabled) @@ -143,11 +198,17 @@ namespace Perspex.Threading } } + /// + /// Raises the event on the dispatcher thread. + /// private void InternalTick() { this.Dispatcher.InvokeAsync(this.RaiseTick, this.priority); } + /// + /// Raises the event. + /// private void RaiseTick() { if (this.Tick != null) diff --git a/Perspex.Base/Threading/MainLoop.cs b/Perspex.Base/Threading/MainLoop.cs index f53aeee5d5..e7efefacc1 100644 --- a/Perspex.Base/Threading/MainLoop.cs +++ b/Perspex.Base/Threading/MainLoop.cs @@ -14,6 +14,9 @@ namespace Perspex.Win32.Threading using Perspex.Threading; using Splat; + /// + /// A main loop in a . + /// internal class MainLoop { private static IPlatformThreadingInterface platform; @@ -21,11 +24,20 @@ namespace Perspex.Win32.Threading private PriorityQueue queue = new PriorityQueue(PriorityQueueType.Maximum); + /// + /// Initializes static members of the class. + /// static MainLoop() { platform = Locator.Current.GetService(); } + /// + /// Runs the main loop. + /// + /// + /// A cancellation token used to exit the main loop. + /// public void Run(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) @@ -64,6 +76,12 @@ namespace Perspex.Win32.Threading } } + /// + /// Invokes a method on the main loop. + /// + /// The method. + /// The priority with which to invoke the method. + /// A task that can be used to track the method's execution. public Task InvokeAsync(Action action, DispatcherPriority priority) { var job = new Job(action, priority); @@ -77,8 +95,16 @@ namespace Perspex.Win32.Threading return job.TaskCompletionSource.Task; } + /// + /// A job to run. + /// private class Job { + /// + /// Initializes a new instance of the class. + /// + /// The method to call. + /// The job priority. public Job(Action action, DispatcherPriority priority) { this.Action = action; @@ -86,11 +112,20 @@ namespace Perspex.Win32.Threading this.TaskCompletionSource = new TaskCompletionSource(); } - public Action Action { get; private set; } + /// + /// Gets the method to call. + /// + public Action Action { get; } - public DispatcherPriority Priority { get; private set; } + /// + /// Gets the job priority. + /// + public DispatcherPriority Priority { get; } - public TaskCompletionSource TaskCompletionSource { get; set; } + /// + /// Gets the task completion source. + /// + public TaskCompletionSource TaskCompletionSource { get; } } } } diff --git a/Perspex.Base/Threading/PerspexScheduler.cs b/Perspex.Base/Threading/PerspexScheduler.cs index c6c8396eec..a1ebbdcf9b 100644 --- a/Perspex.Base/Threading/PerspexScheduler.cs +++ b/Perspex.Base/Threading/PerspexScheduler.cs @@ -8,12 +8,25 @@ namespace Perspex.Threading { using System; using System.Reactive.Concurrency; - using System.Reactive.Disposables; + /// + /// A reactive scheduler that uses Perspex's . + /// public class PerspexScheduler : LocalScheduler { + /// + /// The instance of the . + /// public static readonly PerspexScheduler Instance = new PerspexScheduler(); + /// + /// Initializes a new instance of the class. + /// + private PerspexScheduler() + { + } + + /// public override IDisposable Schedule(TState state, TimeSpan dueTime, Func action) { return DispatcherTimer.Run(