Browse Source

Rename RenderLoop -> DefaultRenderLoop.

Make it overridable and register it in the windowing subsystem, so that
windowing subsystems can provide custom implementations.
Steven Kirk 9 years ago
parent
commit
81d31a4e20

+ 0 - 9
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
         /// </remarks>
         public Styles Styles { get; } = new Styles();
 
-        /// <summary>
-        /// Gets the application's render loop.
-        /// </summary>
-        public IRenderLoop RenderLoop { get; private set; }
-
         /// <summary>
         /// Gets the styling parent of the application, which is null.
         /// </summary>
@@ -172,7 +165,6 @@ namespace Avalonia
             AvaloniaSynchronizationContext.InstallIfNeeded();
             FocusManager = new FocusManager();
             InputManager = new InputManager();
-            RenderLoop = new RenderLoop(60);
 
             AvaloniaLocator.CurrentMutable
                 .Bind<IAccessKeyHandler>().ToTransient<AccessKeyHandler>()
@@ -184,7 +176,6 @@ namespace Avalonia
                 .Bind<IStyler>().ToConstant(_styler)
                 .Bind<ILayoutManager>().ToSingleton<LayoutManager>()
                 .Bind<IRenderer>().ToTransient<Renderer>()
-                .Bind<IRenderLoop>().ToConstant(RenderLoop)
                 .Bind<IApplicationLifecycle>().ToConstant(this);
         }
     }

+ 1 - 1
src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj

@@ -106,7 +106,7 @@
     <Compile Include="Rendering\IRenderLoop.cs" />
     <Compile Include="Rendering\Renderer.cs" />
     <Compile Include="Rendering\RendererMixin.cs" />
-    <Compile Include="Rendering\RenderLoop.cs" />
+    <Compile Include="Rendering\DefaultRenderLoop.cs" />
     <Compile Include="RenderTargetCorruptedException.cs" />
     <Compile Include="VisualTree\IVisual.cs" />
     <Compile Include="Media\Imaging\Bitmap.cs" />

+ 102 - 0
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
+{
+    /// <summary>
+    /// Defines a default render loop that uses a standard timer.
+    /// </summary>
+    /// <remarks>
+    /// This class may be overridden by platform implementations to use a specialized timer
+    /// implementation.
+    /// </remarks>
+    public class DefaultRenderLoop : IRenderLoop
+    {
+        private IPlatformThreadingInterface _threading;
+        private int _subscriberCount;
+        private EventHandler<EventArgs> _tick;
+        private IDisposable _subscription;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DefaultRenderLoop"/> class.
+        /// </summary>
+        /// <param name="framesPerSecond">
+        /// The number of frames per second at which the loop should run.
+        /// </param>
+        public DefaultRenderLoop(int framesPerSecond)
+        {
+            FramesPerSecond = framesPerSecond;
+        }
+
+        /// <summary>
+        /// Gets the number of frames per second at which the loop runs.
+        /// </summary>
+        public int FramesPerSecond { get; }
+
+        /// <inheritdoc/>
+        public event EventHandler<EventArgs> Tick
+        {
+            add
+            {
+                if (_subscriberCount++ == 0)
+                {
+                    Start();
+                }
+
+                _tick += value;
+            }
+
+            remove
+            {
+                if (--_subscriberCount == 0)
+                {
+                    Stop();
+                }
+
+                _tick -= value;
+            }
+        }
+
+        /// <summary>
+        /// Starts the timer.
+        /// </summary>
+        protected void Start()
+        {
+            _subscription = StartCore();
+        }
+
+        /// <summary>
+        /// Provides the implementation of starting the timer.
+        /// </summary>
+        /// <remarks>
+        /// This can be overridden by platform implementations to use a specialized timer
+        /// implementation.
+        /// </remarks>
+        protected virtual IDisposable StartCore()
+        {
+            if (_threading == null)
+            {
+                _threading = AvaloniaLocator.Current.GetService<IPlatformThreadingInterface>();
+            }
+
+            return _threading.StartTimer(TimeSpan.FromSeconds(1.0 / FramesPerSecond), InternalTick);
+        }
+
+        /// <summary>
+        /// Stops the timer.
+        /// </summary>
+        protected void Stop()
+        {
+            _subscription.Dispose();
+            _subscription = null;
+        }
+
+        private void InternalTick()
+        {
+            _tick(this, EventArgs.Empty);
+        }
+    }
+}

+ 6 - 0
src/Avalonia.SceneGraph/Rendering/IRenderLoop.cs

@@ -2,8 +2,14 @@
 
 namespace Avalonia.Rendering
 {
+    /// <summary>
+    /// Defines the interface implemented by an application render loop.
+    /// </summary>
     public interface IRenderLoop
     {
+        /// <summary>
+        /// Raised when the render loop ticks to signal a new frame should be drawn.
+        /// </summary>
         event EventHandler<EventArgs> Tick;
     }
 }

+ 0 - 66
src/Avalonia.SceneGraph/Rendering/RenderLoop.cs

@@ -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<EventArgs> _tick;
-        private IDisposable _subscription;
-
-        public RenderLoop(int fps)
-        {
-            _fps = fps;
-        }
-
-        public event EventHandler<EventArgs> 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<IPlatformThreadingInterface>();
-            }
-
-            _subscription = _threading.StartTimer(TimeSpan.FromSeconds(1.0 / _fps), InternalTick);
-        }
-
-        protected void Stop()
-        {
-            _subscription.Dispose();
-            _subscription = null;
-        }
-
-        private void InternalTick()
-        {
-            _tick(this, EventArgs.Empty);
-        }
-    }
-}

+ 2 - 0
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<IMouseDevice>().ToConstant(GtkMouseDevice.Instance)
                 .Bind<IPlatformSettings>().ToConstant(s_instance)
                 .Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
+                .Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
                 .Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>()
                 .Bind<IPlatformIconLoader>().ToConstant(s_instance);
             _uiThread = Thread.CurrentThread;

+ 2 - 0
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<IMouseDevice>().ToConstant(WindowsMouseDevice.Instance)
                 .Bind<IPlatformSettings>().ToConstant(s_instance)
                 .Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
+                .Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
                 .Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>()
                 .Bind<IWindowingPlatform>().ToConstant(s_instance)
                 .Bind<IPlatformIconLoader>().ToConstant(s_instance);