Browse Source

Rename RenderLoop -> DefaultRenderLoop.

Make it overridable and register it in the windowing subsystem, so that
windowing subsystems can provide custom implementations.
pull/773/head
Steven Kirk 10 years ago
parent
commit
81d31a4e20
  1. 9
      src/Avalonia.Controls/Application.cs
  2. 2
      src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
  3. 102
      src/Avalonia.SceneGraph/Rendering/DefaultRenderLoop.cs
  4. 6
      src/Avalonia.SceneGraph/Rendering/IRenderLoop.cs
  5. 66
      src/Avalonia.SceneGraph/Rendering/RenderLoop.cs
  6. 2
      src/Gtk/Avalonia.Gtk/GtkPlatform.cs
  7. 2
      src/Windows/Avalonia.Win32/Win32Platform.cs

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

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

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
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
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);

Loading…
Cancel
Save