csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.8 KiB
87 lines
2.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using Avalonia.Logging;
|
|
using Avalonia.Media;
|
|
using Avalonia.Rendering.Composition.Transport;
|
|
|
|
namespace Avalonia.Rendering.Composition.Server;
|
|
|
|
internal sealed class ServerCompositionCustomVisual : ServerCompositionContainerVisual, IServerClockItem
|
|
{
|
|
private readonly CompositionCustomVisualHandler _handler;
|
|
private bool _wantsNextAnimationFrameAfterTick;
|
|
internal ServerCompositionCustomVisual(ServerCompositor compositor, CompositionCustomVisualHandler handler) : base(compositor)
|
|
{
|
|
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
|
|
_handler.Attach(this);
|
|
}
|
|
|
|
public void DispatchMessages(List<object> messages)
|
|
{
|
|
foreach(var message in messages)
|
|
{
|
|
try
|
|
{
|
|
_handler.OnMessage(message);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.TryGet(LogEventLevel.Error, LogArea.Visual)
|
|
?.Log(_handler, $"Exception in {_handler.GetType().Name}.{nameof(CompositionCustomVisualHandler.OnMessage)} {{0}}", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnTick()
|
|
{
|
|
_wantsNextAnimationFrameAfterTick = false;
|
|
_handler.OnAnimationFrameUpdate();
|
|
if (!_wantsNextAnimationFrameAfterTick)
|
|
Compositor.RemoveFromClock(this);
|
|
}
|
|
|
|
public override Rect OwnContentBounds => _handler.GetRenderBounds();
|
|
|
|
protected override void OnAttachedToRoot(ServerCompositionTarget target)
|
|
{
|
|
if (_wantsNextAnimationFrameAfterTick)
|
|
Compositor.AddToClock(this);
|
|
base.OnAttachedToRoot(target);
|
|
}
|
|
|
|
protected override void OnDetachedFromRoot(ServerCompositionTarget target)
|
|
{
|
|
Compositor.RemoveFromClock(this);
|
|
base.OnDetachedFromRoot(target);
|
|
}
|
|
|
|
internal void HandlerInvalidate() => ValuesInvalidated();
|
|
|
|
internal void HandlerInvalidate(Rect rc)
|
|
{
|
|
Root?.AddDirtyRect(rc.TransformToAABB(GlobalTransformMatrix));
|
|
}
|
|
|
|
internal void HandlerRegisterForNextAnimationFrameUpdate()
|
|
{
|
|
_wantsNextAnimationFrameAfterTick = true;
|
|
if (Root != null)
|
|
Compositor.AddToClock(this);
|
|
}
|
|
|
|
protected override void RenderCore(CompositorDrawingContextProxy canvas, Rect currentTransformedClip,
|
|
IDirtyRectTracker dirtyRects)
|
|
{
|
|
using var context = new ImmediateDrawingContext(canvas, false);
|
|
try
|
|
{
|
|
_handler.Render(context, currentTransformedClip);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.TryGet(LogEventLevel.Error, LogArea.Visual)
|
|
?.Log(_handler, $"Exception in {_handler.GetType().Name}.{nameof(CompositionCustomVisualHandler.OnRender)} {{0}}", e);
|
|
}
|
|
}
|
|
}
|
|
|