Browse Source

Removed IRendererFactory.

Make the `ITopLevelImpl` create the renderer instead.
pull/827/head
Steven Kirk 9 years ago
parent
commit
d2eca3968b
  1. 5
      .ncrunch/Avalonia.Win32.Interop.v3.ncrunchproject
  2. 7
      src/Avalonia.Controls/Platform/ITopLevelImpl.cs
  3. 3
      src/Avalonia.Controls/TopLevel.cs
  4. 18
      src/Avalonia.Visuals/Rendering/IRendererFactory.cs
  5. 7
      src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs
  6. 8
      src/Gtk/Avalonia.Gtk/GtkPlatform.cs
  7. 6
      src/Gtk/Avalonia.Gtk/TopLevelImpl.cs
  8. 9
      src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
  9. 6
      src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
  10. 6
      src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs
  11. 1
      src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
  12. 6
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs
  13. 15
      src/Windows/Avalonia.Win32/Win32Platform.cs
  14. 10
      src/Windows/Avalonia.Win32/WindowImpl.cs
  15. 35
      tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs
  16. 31
      tests/Avalonia.Controls.UnitTests/WindowTests.cs
  17. 5
      tests/Avalonia.Input.UnitTests/MouseDeviceTests.cs
  18. 6
      tests/Avalonia.LeakTests/ControlTests.cs
  19. 29
      tests/Avalonia.UnitTests/MockRendererFactory.cs
  20. 3
      tests/Avalonia.UnitTests/TestRoot.cs
  21. 19
      tests/Avalonia.UnitTests/TestServices.cs
  22. 17
      tests/Avalonia.UnitTests/UnitTestApplication.cs
  23. 16
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
  24. 13
      tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs
  25. 30
      tests/Avalonia.Visuals.UnitTests/VisualTests.cs

5
.ncrunch/Avalonia.Win32.Interop.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings>
</ProjectConfiguration>

7
src/Avalonia.Controls/Platform/ITopLevelImpl.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Rendering;
using JetBrains.Annotations;
namespace Avalonia.Platform
@ -60,6 +61,12 @@ namespace Avalonia.Platform
/// </summary>
Action<double> ScalingChanged { get; set; }
/// <summary>
/// Creates a new renderer for the toplevel.
/// </summary>
/// <param name="root">The toplevel.</param>
IRenderer CreateRenderer(IRenderRoot root);
/// <summary>
/// Invalidates a rect on the toplevel.
/// </summary>

3
src/Avalonia.Controls/TopLevel.cs

@ -90,8 +90,7 @@ namespace Avalonia.Controls
_renderInterface = TryGetService<IPlatformRenderInterface>(dependencyResolver);
var renderLoop = TryGetService<IRenderLoop>(dependencyResolver);
var rendererFactory = TryGetService<IRendererFactory>(dependencyResolver);
Renderer = rendererFactory?.CreateRenderer(this, renderLoop);
Renderer = impl.CreateRenderer(this);
impl.SetInputRoot(this);

18
src/Avalonia.Visuals/Rendering/IRendererFactory.cs

@ -1,18 +0,0 @@
using System;
namespace Avalonia.Rendering
{
/// <summary>
/// Defines a factory for creating <see cref="IRenderer"/> instances.
/// </summary>
public interface IRendererFactory
{
/// <summary>
/// Creates a new renderer for the specified render root.
/// </summary>
/// <param name="root">The render root.</param>
/// <param name="renderLoop">The render loop.</param>
/// <returns>An instance of an <see cref="IRenderer"/>.</returns>
IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop);
}
}

7
src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs

@ -20,11 +20,6 @@ namespace Avalonia.Rendering
/// </remarks>
public class ImmediateRenderer : RendererBase, IRenderer, IVisualBrushRenderer
{
class ImmediateRendererFactory : IRendererFactory
{
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop) => new ImmediateRenderer(root);
}
private readonly IVisual _root;
private readonly IRenderRoot _renderRoot;
private IRenderTarget _renderTarget;
@ -41,8 +36,6 @@ namespace Avalonia.Rendering
_renderRoot = root as IRenderRoot;
}
public static IRendererFactory Factory { get; } = new ImmediateRendererFactory();
/// <inheritdoc/>
public bool DrawFps { get; set; }

8
src/Gtk/Avalonia.Gtk/GtkPlatform.cs

@ -28,7 +28,7 @@ namespace Avalonia.Gtk
using Rendering;
using Gtk = global::Gtk;
public class GtkPlatform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader, IRendererFactory
public class GtkPlatform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader
{
private static readonly GtkPlatform s_instance = new GtkPlatform();
private static Thread _uiThread;
@ -53,7 +53,6 @@ namespace Avalonia.Gtk
.Bind<IKeyboardDevice>().ToConstant(GtkKeyboardDevice.Instance)
.Bind<IPlatformSettings>().ToConstant(s_instance)
.Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
.Bind<IRendererFactory>().ToConstant(s_instance)
.Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
.Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>()
.Bind<IPlatformIconLoader>().ToConstant(s_instance);
@ -112,11 +111,6 @@ namespace Avalonia.Gtk
return new PopupImpl();
}
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop)
{
return new ImmediateRenderer(root);
}
public IWindowIconImpl LoadIcon(string fileName)
{
return new IconImpl(new Gdk.Pixbuf(fileName));

6
src/Gtk/Avalonia.Gtk/TopLevelImpl.cs

@ -10,6 +10,7 @@ using Gdk;
using Action = System.Action;
using WindowEdge = Avalonia.Controls.WindowEdge;
using GLib;
using Avalonia.Rendering;
namespace Avalonia.Gtk
{
@ -141,6 +142,11 @@ namespace Avalonia.Gtk
return new PopupImpl();
}
public IRenderer CreateRenderer(IRenderRoot root)
{
return new ImmediateRenderer(root);
}
public void Invalidate(Rect rect)
{
if (_widget?.GdkWindow != null)

9
src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs

@ -15,7 +15,7 @@ using Avalonia.Gtk3;
namespace Avalonia.Gtk3
{
public class Gtk3Platform : IWindowingPlatform, IPlatformSettings, IPlatformThreadingInterface, IRendererFactory
public class Gtk3Platform : IWindowingPlatform, IPlatformSettings, IPlatformThreadingInterface
{
internal static readonly Gtk3Platform Instance = new Gtk3Platform();
internal static readonly MouseDevice Mouse = new MouseDevice();
@ -37,9 +37,7 @@ namespace Avalonia.Gtk3
.Bind<IPlatformSettings>().ToConstant(Instance)
.Bind<IPlatformThreadingInterface>().ToConstant(Instance)
.Bind<ISystemDialogImpl>().ToSingleton<SystemDialog>()
.Bind<IRendererFactory>().ToConstant(Instance)
.Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
.Bind<IRendererFactory>().ToConstant(ImmediateRenderer.Factory)
.Bind<IPlatformIconLoader>().ToConstant(new PlatformIconLoader());
}
@ -53,11 +51,6 @@ namespace Avalonia.Gtk3
public IPopupImpl CreatePopup() => new PopupImpl();
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop)
{
return new ImmediateRenderer(root);
}
public Size DoubleClickSize => new Size(4, 4);
public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(100); //STUB

6
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@ -9,6 +9,7 @@ using Avalonia.Gtk3.Interop;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Platform;
using Avalonia.Rendering;
namespace Avalonia.Gtk3
{
@ -354,5 +355,10 @@ namespace Avalonia.Gtk3
IntPtr IPlatformHandle.Handle => Native.GetNativeGdkWindowHandle(Native.GtkWidgetGetWindow(GtkWidget));
public IEnumerable<object> Surfaces => new object[] {Handle, _framebuffer};
public IRenderer CreateRenderer(IRenderRoot root)
{
return new ImmediateRenderer(root);
}
}
}

6
src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs

@ -5,6 +5,7 @@ using System.Text;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Threading;
namespace Avalonia.LinuxFramebuffer
@ -24,6 +25,11 @@ namespace Avalonia.LinuxFramebuffer
mice.Event += e => Input?.Invoke(e);
}
public IRenderer CreateRenderer(IRenderRoot root)
{
return new ImmediateRenderer(root);
}
public void Dispose()
{
throw new NotSupportedException();

1
src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs

@ -34,7 +34,6 @@ namespace Avalonia.LinuxFramebuffer
.Bind<IStandardCursorFactory>().ToTransient<CursorFactoryStub>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
.Bind<IPlatformSettings>().ToSingleton<PlatformSettings>()
.Bind<IRendererFactory>().ToConstant(ImmediateRenderer.Factory)
.Bind<IPlatformThreadingInterface>().ToConstant(PlatformThreadingInterface.Instance)
.Bind<IRenderLoop>().ToConstant(PlatformThreadingInterface.Instance);
}

6
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@ -13,6 +13,7 @@ using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Layout;
using Avalonia.Platform;
using Avalonia.Rendering;
using Key = Avalonia.Input.Key;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MouseButton = System.Windows.Input.MouseButton;
@ -88,6 +89,11 @@ namespace Avalonia.Win32.Interop.Wpf
_ttl.ScalingChanged?.Invoke(_ttl.Scaling);
}
public IRenderer CreateRenderer(IRenderRoot root)
{
return new ImmediateRenderer(root);
}
public void Dispose()
{
_ttl.Closed?.Invoke();

15
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -39,10 +39,9 @@ namespace Avalonia
namespace Avalonia.Win32
{
partial class Win32Platform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader, IRendererFactory
partial class Win32Platform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader
{
private static readonly Win32Platform s_instance = new Win32Platform();
private static bool s_deferredRendering = true;
private static uint _uiThread;
private UnmanagedMethods.WndProc _wndProcDelegate;
private IntPtr _hwnd;
@ -59,6 +58,8 @@ namespace Avalonia.Win32
CreateMessageWindow();
}
public static bool UseDeferredRendering { get; set; }
public Size DoubleClickSize => new Size(
UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CXDOUBLECLK),
UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYDOUBLECLK));
@ -79,12 +80,11 @@ namespace Avalonia.Win32
.Bind<IPlatformSettings>().ToConstant(s_instance)
.Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
.Bind<IRenderLoop>().ToConstant(new RenderLoop(60))
.Bind<IRendererFactory>().ToConstant(s_instance)
.Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>()
.Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<IPlatformIconLoader>().ToConstant(s_instance);
s_deferredRendering = deferredRendering;
UseDeferredRendering = deferredRendering;
_uiThread = UnmanagedMethods.GetCurrentThreadId();
}
@ -208,12 +208,5 @@ namespace Avalonia.Win32
{
return new PopupImpl();
}
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop)
{
return s_deferredRendering ?
(IRenderer)new DeferredRenderer(root, renderLoop) :
(IRenderer)new ImmediateRenderer(root);
}
}
}

10
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -15,6 +15,7 @@ using Avalonia.Platform;
using Avalonia.Win32.Input;
using Avalonia.Win32.Interop;
using static Avalonia.Win32.Interop.UnmanagedMethods;
using Avalonia.Rendering;
#if NETSTANDARD
using Win32Exception = Avalonia.Win32.NetStandard.AvaloniaWin32Exception;
#endif
@ -90,6 +91,15 @@ namespace Avalonia.Win32
}
}
public IRenderer CreateRenderer(IRenderRoot root)
{
var loop = AvaloniaLocator.Current.GetService<IRenderLoop>();
return Win32Platform.UseDeferredRendering ?
(IRenderer)new DeferredRenderer(root, loop) :
new ImmediateRenderer(root);
}
public void Resize(Size value)
{
if (value != ClientSize)

35
tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs

@ -188,12 +188,10 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Showing_Should_Start_Renderer()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(TestServices.StyledWindow
.With(renderer: (root, loop) => renderer.Object)))
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new TestWindowBase();
var renderer = new Mock<IRenderer>();
var target = new TestWindowBase(renderer.Object);
target.Show();
@ -204,12 +202,11 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Hiding_Should_Stop_Renderer()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(TestServices.StyledWindow
.With(renderer: (root, loop) => renderer.Object)))
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new TestWindowBase();
var renderer = new Mock<IRenderer>();
var target = new TestWindowBase(renderer.Object);
target.Show();
target.Hide();
@ -221,14 +218,14 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Renderer_Should_Be_Disposed_When_Impl_Signals_Close()
{
var renderer = new Mock<IRenderer>();
var windowImpl = new Mock<IPopupImpl>();
windowImpl.Setup(x => x.Scaling).Returns(1);
windowImpl.SetupProperty(x => x.Closed);
using (UnitTestApplication.Start(TestServices.StyledWindow
.With(renderer: (root, loop) => renderer.Object)))
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var renderer = new Mock<IRenderer>();
var windowImpl = new Mock<IPopupImpl>();
windowImpl.Setup(x => x.Scaling).Returns(1);
windowImpl.SetupProperty(x => x.Closed);
windowImpl.Setup(x => x.CreateRenderer(It.IsAny<IRenderRoot>())).Returns(renderer.Object);
var target = new TestWindowBase(windowImpl.Object);
target.Show();
@ -252,8 +249,10 @@ namespace Avalonia.Controls.UnitTests
{
public bool IsClosed { get; private set; }
public TestWindowBase()
: base(Mock.Of<IWindowBaseImpl>(x => x.Scaling == 1))
public TestWindowBase(IRenderer renderer = null)
: base(Mock.Of<IWindowBaseImpl>(x =>
x.Scaling == 1 &&
x.CreateRenderer(It.IsAny<IRenderRoot>()) == renderer))
{
}

31
tests/Avalonia.Controls.UnitTests/WindowTests.cs

@ -4,6 +4,7 @@
// </copyright>
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using Avalonia.Platform;
using Avalonia.Rendering;
@ -189,12 +190,10 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Showing_Should_Start_Renderer()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(TestServices.StyledWindow
.With(renderer: (root, loop) => renderer.Object)))
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new Window();
var renderer = new Mock<IRenderer>();
var target = new Window(CreateImpl(renderer));
target.Show();
@ -205,12 +204,11 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void ShowDialog_Should_Start_Renderer()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(TestServices.StyledWindow
.With(renderer: (root, loop) => renderer.Object)))
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new Window();
var renderer = new Mock<IRenderer>();
var target = new Window(CreateImpl(renderer));
target.Show();
@ -221,12 +219,10 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Hiding_Should_Stop_Renderer()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(TestServices.StyledWindow
.With(renderer: (root, loop) => renderer.Object)))
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new Window();
var renderer = new Mock<IRenderer>();
var target = new Window(CreateImpl(renderer));
target.Show();
target.Hide();
@ -241,5 +237,12 @@ namespace Avalonia.Controls.UnitTests
// AvaloniaLocator scopes.
((IList<Window>)Window.OpenWindows).Clear();
}
private IWindowImpl CreateImpl(Mock<IRenderer> renderer)
{
return Mock.Of<IWindowImpl>(x =>
x.Scaling == 1 &&
x.CreateRenderer(It.IsAny<IRenderRoot>()) == renderer.Object);
}
}
}

5
tests/Avalonia.Input.UnitTests/MouseDeviceTests.cs

@ -28,6 +28,7 @@ namespace Avalonia.Input.UnitTests
var root = new TestRoot
{
MouseDevice = new MouseDevice(),
Renderer = renderer.Object,
Child = new Panel
{
Children =
@ -78,9 +79,7 @@ namespace Avalonia.Input.UnitTests
private IDisposable TestApplication(IRenderer renderer)
{
return UnitTestApplication.Start(
new TestServices(
inputManager: new InputManager(),
renderer: (root, loop) => renderer));
new TestServices(inputManager: new InputManager()));
}
}
}

6
tests/Avalonia.LeakTests/ControlTests.cs

@ -318,12 +318,11 @@ namespace Avalonia.LeakTests
var impl = new Mock<IWindowImpl>();
impl.SetupGet(x => x.Scaling).Returns(1);
impl.SetupProperty(x => x.Closed);
impl.Setup(x => x.CreateRenderer(It.IsAny<IRenderRoot>())).Returns(renderer.Object);
impl.Setup(x => x.Dispose()).Callback(() => impl.Object.Closed());
AvaloniaLocator.CurrentMutable.Bind<IWindowingPlatform>()
.ToConstant(new MockWindowingPlatform(() => impl.Object));
AvaloniaLocator.CurrentMutable.Bind<IRendererFactory>()
.ToConstant(new MockRendererFactory(renderer.Object));
var window = new Window()
{
Content = new Button()
@ -336,8 +335,7 @@ namespace Avalonia.LeakTests
private IDisposable Start()
{
var services = TestServices.StyledWindow.With(renderer: (root, loop) => new NullRenderer());
return UnitTestApplication.Start(services);
return UnitTestApplication.Start(TestServices.StyledWindow);
}
private class Node

29
tests/Avalonia.UnitTests/MockRendererFactory.cs

@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Rendering;
namespace Avalonia.UnitTests
{
public class MockRendererFactory : IRendererFactory
{
private readonly Func<IRenderRoot, IRenderLoop, IRenderer> _cb;
public MockRendererFactory(Func<IRenderRoot, IRenderLoop, IRenderer> cb = null)
{
_cb = cb;
}
public MockRendererFactory(IRenderer renderer) : this((_, __) => renderer)
{
}
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop)
{
return _cb?.Invoke(root, renderLoop);
}
}
}

3
tests/Avalonia.UnitTests/TestRoot.cs

@ -21,9 +21,6 @@ namespace Avalonia.UnitTests
public TestRoot()
{
var rendererFactory = AvaloniaLocator.Current.GetService<IRendererFactory>();
var renderLoop = AvaloniaLocator.Current.GetService<IRenderLoop>();
Renderer = rendererFactory?.CreateRenderer(this, renderLoop);
}
event EventHandler<NameScopeEventArgs> INameScope.Registered

19
tests/Avalonia.UnitTests/TestServices.cs

@ -23,9 +23,7 @@ namespace Avalonia.UnitTests
assetLoader: new AssetLoader(),
layoutManager: new LayoutManager(),
platform: new AppBuilder().RuntimePlatform,
renderer: (_, __) => Mock.Of<IRenderer>(),
renderInterface: new MockPlatformRenderInterface(),
renderLoop: Mock.Of<IRenderLoop>(),
standardCursorFactory: Mock.Of<IStandardCursorFactory>(),
styler: new Styler(),
theme: () => CreateDefaultTheme(),
@ -47,9 +45,6 @@ namespace Avalonia.UnitTests
public static readonly TestServices MockWindowingPlatform = new TestServices(
windowingPlatform: new MockWindowingPlatform());
public static readonly TestServices RealDeferredRenderer = new TestServices(
renderer: (root, loop) => new DeferredRenderer(root, loop));
public static readonly TestServices RealFocus = new TestServices(
focusManager: new FocusManager(),
keyboardDevice: () => new KeyboardDevice(),
@ -71,7 +66,6 @@ namespace Avalonia.UnitTests
ILayoutManager layoutManager = null,
Func<IMouseDevice> mouseDevice = null,
IRuntimePlatform platform = null,
Func<IRenderRoot, IRenderLoop, IRenderer> renderer = null,
IPlatformRenderInterface renderInterface = null,
IRenderLoop renderLoop = null,
IScheduler scheduler = null,
@ -79,6 +73,7 @@ namespace Avalonia.UnitTests
IStyler styler = null,
Func<Styles> theme = null,
IPlatformThreadingInterface threadingInterface = null,
IWindowImpl windowImpl = null,
IWindowingPlatform windowingPlatform = null)
{
AssetLoader = assetLoader;
@ -89,14 +84,13 @@ namespace Avalonia.UnitTests
LayoutManager = layoutManager;
MouseDevice = mouseDevice;
Platform = platform;
Renderer = renderer;
RenderInterface = renderInterface;
RenderLoop = renderLoop;
Scheduler = scheduler;
StandardCursorFactory = standardCursorFactory;
Styler = styler;
Theme = theme;
ThreadingInterface = threadingInterface;
WindowImpl = windowImpl;
WindowingPlatform = windowingPlatform;
}
@ -108,14 +102,13 @@ namespace Avalonia.UnitTests
public ILayoutManager LayoutManager { get; }
public Func<IMouseDevice> MouseDevice { get; }
public IRuntimePlatform Platform { get; }
public Func<IRenderRoot, IRenderLoop, IRenderer> Renderer { get; }
public IPlatformRenderInterface RenderInterface { get; }
public IRenderLoop RenderLoop { get; }
public IScheduler Scheduler { get; }
public IStandardCursorFactory StandardCursorFactory { get; }
public IStyler Styler { get; }
public Func<Styles> Theme { get; }
public IPlatformThreadingInterface ThreadingInterface { get; }
public IWindowImpl WindowImpl { get; }
public IWindowingPlatform WindowingPlatform { get; }
public TestServices With(
@ -127,7 +120,6 @@ namespace Avalonia.UnitTests
ILayoutManager layoutManager = null,
Func<IMouseDevice> mouseDevice = null,
IRuntimePlatform platform = null,
Func<IRenderRoot, IRenderLoop, IRenderer> renderer = null,
IPlatformRenderInterface renderInterface = null,
IRenderLoop renderLoop = null,
IScheduler scheduler = null,
@ -147,15 +139,14 @@ namespace Avalonia.UnitTests
layoutManager: layoutManager ?? LayoutManager,
mouseDevice: mouseDevice ?? MouseDevice,
platform: platform ?? Platform,
renderer: renderer ?? Renderer,
renderInterface: renderInterface ?? RenderInterface,
renderLoop: renderLoop ?? RenderLoop,
scheduler: scheduler ?? Scheduler,
standardCursorFactory: standardCursorFactory ?? StandardCursorFactory,
styler: styler ?? Styler,
theme: theme ?? Theme,
threadingInterface: threadingInterface ?? ThreadingInterface,
windowingPlatform: windowingPlatform ?? WindowingPlatform);
windowingPlatform: windowingPlatform ?? WindowingPlatform,
windowImpl: windowImpl ?? WindowImpl);
}
private static Styles CreateDefaultTheme()

17
tests/Avalonia.UnitTests/UnitTestApplication.cs

@ -53,9 +53,7 @@ namespace Avalonia.UnitTests
.Bind<ILayoutManager>().ToConstant(Services.LayoutManager)
.Bind<IMouseDevice>().ToConstant(Services.MouseDevice?.Invoke())
.Bind<IRuntimePlatform>().ToConstant(Services.Platform)
.Bind<IRendererFactory>().ToConstant(new RendererFactory(Services.Renderer))
.Bind<IPlatformRenderInterface>().ToConstant(Services.RenderInterface)
.Bind<IRenderLoop>().ToConstant(Services.RenderLoop)
.Bind<IPlatformThreadingInterface>().ToConstant(Services.ThreadingInterface)
.Bind<IScheduler>().ToConstant(Services.Scheduler)
.Bind<IStandardCursorFactory>().ToConstant(Services.StandardCursorFactory)
@ -69,20 +67,5 @@ namespace Avalonia.UnitTests
Styles.AddRange(styles);
}
}
private class RendererFactory : IRendererFactory
{
Func<IRenderRoot, IRenderLoop, IRenderer> _func;
public RendererFactory(Func<IRenderRoot, IRenderLoop, IRenderer> func)
{
_func = func;
}
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop)
{
return _func?.Invoke(root, renderLoop);
}
}
}
}

16
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs

@ -38,6 +38,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
@ -65,6 +66,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
@ -101,6 +103,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
@ -129,6 +132,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
@ -172,6 +176,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
@ -225,6 +230,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
@ -273,6 +279,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
container.Measure(Size.Infinity);
container.Arrange(new Rect(container.DesiredSize));
@ -320,6 +327,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
@ -392,6 +400,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
scroll.UpdateChild();
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
@ -437,6 +446,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
@ -475,6 +485,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new DeferredRenderer(root, null);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
Assert.Equal(new Rect(100, 100, 200, 200), border.Bounds);
@ -491,10 +502,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
private IDisposable TestApplication()
{
return UnitTestApplication.Start(
new TestServices(
renderInterface: new MockPlatformRenderInterface(),
renderer: (root, loop) => new DeferredRenderer(root, loop)));
return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
}
}
}

13
tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs

@ -35,6 +35,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -72,6 +73,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -101,6 +103,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -145,6 +148,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -199,6 +203,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -257,6 +262,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
container.Measure(Size.Infinity);
container.Arrange(new Rect(container.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -305,6 +311,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
}
};
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -378,6 +385,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
scroll.UpdateChild();
root.Renderer = new ImmediateRenderer(root);
root.Measure(Size.Infinity);
root.Arrange(new Rect(container.DesiredSize));
root.Renderer.Paint(new Rect(root.ClientSize));
@ -408,10 +416,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
private IDisposable TestApplication()
{
return UnitTestApplication.Start(
new TestServices(
renderInterface: new MockPlatformRenderInterface(),
renderer: (root, loop) => new ImmediateRenderer(root)));
return UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
}
}
}

30
tests/Avalonia.Visuals.UnitTests/VisualTests.cs

@ -152,34 +152,32 @@ namespace Avalonia.Visuals.UnitTests
public void Attaching_To_Visual_Tree_Should_Invalidate_Visual()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(new TestServices(renderer: (root, loop) => renderer.Object)))
var child = new Decorator();
var root = new TestRoot
{
var child = new Decorator();
var root = new TestRoot();
Renderer = renderer.Object,
};
root.Child = child;
root.Child = child;
renderer.Verify(x => x.AddDirty(child));
}
renderer.Verify(x => x.AddDirty(child));
}
[Fact]
public void Detaching_From_Visual_Tree_Should_Invalidate_Visual()
{
var renderer = new Mock<IRenderer>();
using (UnitTestApplication.Start(new TestServices(renderer: (root, loop) => renderer.Object)))
var child = new Decorator();
var root = new TestRoot
{
var child = new Decorator();
var root = new TestRoot();
Renderer = renderer.Object,
};
root.Child = child;
renderer.ResetCalls();
root.Child = null;
root.Child = child;
renderer.ResetCalls();
root.Child = null;
renderer.Verify(x => x.AddDirty(child));
}
renderer.Verify(x => x.AddDirty(child));
}
[Fact]

Loading…
Cancel
Save