// 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 IRuntimePlatform _runtime;
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(InternalTick);
}
///
/// Provides the implementation of starting the timer.
///
/// The method to call on each tick.
///
/// This can be overridden by platform implementations to use a specialized timer
/// implementation.
///
protected virtual IDisposable StartCore(Action tick)
{
if (_runtime == null)
{
_runtime = AvaloniaLocator.Current.GetService();
}
return _runtime.StartSystemTimer(TimeSpan.FromSeconds(1.0 / FramesPerSecond), tick);
}
///
/// Stops the timer.
///
protected void Stop()
{
_subscription.Dispose();
_subscription = null;
}
private void InternalTick()
{
_tick(this, EventArgs.Empty);
}
}
}