diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs
index 0fd4572088..69b3152e9b 100644
--- a/src/Avalonia.Controls/Application.cs
+++ b/src/Avalonia.Controls/Application.cs
@@ -2,10 +2,8 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
-using System.Reflection;
using System.Threading;
using Avalonia.Controls;
-using Avalonia.Controls.Platform;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Input.Platform;
@@ -112,11 +110,6 @@ namespace Avalonia
///
public Styles Styles { get; } = new Styles();
- ///
- /// Gets the application's render loop.
- ///
- public IRenderLoop RenderLoop { get; private set; }
-
///
/// Gets the styling parent of the application, which is null.
///
@@ -172,7 +165,6 @@ namespace Avalonia
AvaloniaSynchronizationContext.InstallIfNeeded();
FocusManager = new FocusManager();
InputManager = new InputManager();
- RenderLoop = new RenderLoop(60);
AvaloniaLocator.CurrentMutable
.Bind().ToTransient()
@@ -184,7 +176,6 @@ namespace Avalonia
.Bind().ToConstant(_styler)
.Bind().ToSingleton()
.Bind().ToTransient()
- .Bind().ToConstant(RenderLoop)
.Bind().ToConstant(this);
}
}
diff --git a/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj b/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
index 320590ab5e..18f5c58c61 100644
--- a/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
+++ b/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
@@ -106,7 +106,7 @@
-
+
diff --git a/src/Avalonia.SceneGraph/Rendering/DefaultRenderLoop.cs b/src/Avalonia.SceneGraph/Rendering/DefaultRenderLoop.cs
new file mode 100644
index 0000000000..5210b0a98f
--- /dev/null
+++ b/src/Avalonia.SceneGraph/Rendering/DefaultRenderLoop.cs
@@ -0,0 +1,102 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using Avalonia.Platform;
+
+namespace Avalonia.Rendering
+{
+ ///
+ /// Defines a default render loop that uses a standard timer.
+ ///
+ ///
+ /// This class may be overridden by platform implementations to use a specialized timer
+ /// implementation.
+ ///
+ public class DefaultRenderLoop : IRenderLoop
+ {
+ private IPlatformThreadingInterface _threading;
+ private int _subscriberCount;
+ private EventHandler _tick;
+ private IDisposable _subscription;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The number of frames per second at which the loop should run.
+ ///
+ public DefaultRenderLoop(int framesPerSecond)
+ {
+ FramesPerSecond = framesPerSecond;
+ }
+
+ ///
+ /// Gets the number of frames per second at which the loop runs.
+ ///
+ public int FramesPerSecond { get; }
+
+ ///
+ public event EventHandler Tick
+ {
+ add
+ {
+ if (_subscriberCount++ == 0)
+ {
+ Start();
+ }
+
+ _tick += value;
+ }
+
+ remove
+ {
+ if (--_subscriberCount == 0)
+ {
+ Stop();
+ }
+
+ _tick -= value;
+ }
+ }
+
+ ///
+ /// Starts the timer.
+ ///
+ protected void Start()
+ {
+ _subscription = StartCore();
+ }
+
+ ///
+ /// Provides the implementation of starting the timer.
+ ///
+ ///
+ /// This can be overridden by platform implementations to use a specialized timer
+ /// implementation.
+ ///
+ protected virtual IDisposable StartCore()
+ {
+ if (_threading == null)
+ {
+ _threading = AvaloniaLocator.Current.GetService();
+ }
+
+ return _threading.StartTimer(TimeSpan.FromSeconds(1.0 / FramesPerSecond), InternalTick);
+ }
+
+ ///
+ /// Stops the timer.
+ ///
+ protected void Stop()
+ {
+ _subscription.Dispose();
+ _subscription = null;
+ }
+
+ private void InternalTick()
+ {
+ _tick(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/Avalonia.SceneGraph/Rendering/IRenderLoop.cs b/src/Avalonia.SceneGraph/Rendering/IRenderLoop.cs
index 504dc185a2..049ad1665c 100644
--- a/src/Avalonia.SceneGraph/Rendering/IRenderLoop.cs
+++ b/src/Avalonia.SceneGraph/Rendering/IRenderLoop.cs
@@ -2,8 +2,14 @@
namespace Avalonia.Rendering
{
+ ///
+ /// Defines the interface implemented by an application render loop.
+ ///
public interface IRenderLoop
{
+ ///
+ /// Raised when the render loop ticks to signal a new frame should be drawn.
+ ///
event EventHandler Tick;
}
}
\ No newline at end of file
diff --git a/src/Avalonia.SceneGraph/Rendering/RenderLoop.cs b/src/Avalonia.SceneGraph/Rendering/RenderLoop.cs
deleted file mode 100644
index a7ba01b1bc..0000000000
--- a/src/Avalonia.SceneGraph/Rendering/RenderLoop.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-using System;
-using Avalonia.Platform;
-
-namespace Avalonia.Rendering
-{
- public class RenderLoop : IRenderLoop
- {
- private readonly int _fps;
- private IPlatformThreadingInterface _threading;
- private int _subscriberCount;
- private EventHandler _tick;
- private IDisposable _subscription;
-
- public RenderLoop(int fps)
- {
- _fps = fps;
- }
-
- public event EventHandler Tick
- {
- add
- {
- if (_subscriberCount++ == 0)
- {
- Start();
- }
-
- _tick += value;
- }
-
- remove
- {
- if (--_subscriberCount == 0)
- {
- Stop();
- }
-
- _tick -= value;
- }
- }
-
- protected void Start()
- {
- if (_threading == null)
- {
- _threading = AvaloniaLocator.Current.GetService();
- }
-
- _subscription = _threading.StartTimer(TimeSpan.FromSeconds(1.0 / _fps), InternalTick);
- }
-
- protected void Stop()
- {
- _subscription.Dispose();
- _subscription = null;
- }
-
- private void InternalTick()
- {
- _tick(this, EventArgs.Empty);
- }
- }
-}
diff --git a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
index e79c51915d..aaeba75b50 100644
--- a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
+++ b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
@@ -25,6 +25,7 @@ namespace Avalonia
namespace Avalonia.Gtk
{
using System.IO;
+ using Rendering;
using Gtk = global::Gtk;
public class GtkPlatform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader
@@ -53,6 +54,7 @@ namespace Avalonia.Gtk
.Bind().ToConstant(GtkMouseDevice.Instance)
.Bind().ToConstant(s_instance)
.Bind().ToConstant(s_instance)
+ .Bind().ToConstant(new DefaultRenderLoop(60))
.Bind().ToSingleton()
.Bind().ToConstant(s_instance);
_uiThread = Thread.CurrentThread;
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index 4aa1346a98..9b65e64e00 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -16,6 +16,7 @@ using Avalonia.Win32.Input;
using Avalonia.Win32.Interop;
using Avalonia.Controls;
using System.IO;
+using Avalonia.Rendering;
namespace Avalonia
{
@@ -65,6 +66,7 @@ namespace Avalonia.Win32
.Bind().ToConstant(WindowsMouseDevice.Instance)
.Bind().ToConstant(s_instance)
.Bind().ToConstant(s_instance)
+ .Bind().ToConstant(new DefaultRenderLoop(60))
.Bind().ToSingleton()
.Bind().ToConstant(s_instance)
.Bind().ToConstant(s_instance);