using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Expressions;
using Avalonia.Rendering.Composition.Transport;
using Avalonia.Utilities;
namespace Avalonia.Rendering.Composition.Server
{
///
/// Server-side counterpart.
/// Is responsible for animation activation and invalidation
///
internal abstract class ServerObject : SimpleServerObject, IExpressionObject
{
private uint _activationCount;
private ServerObjectAnimations? _animations;
public ServerObjectAnimations? Animations => _animations;
public ServerObjectAnimations GetOrCreateAnimations() => _animations ??= new(this);
public bool IsActive => _activationCount != 0;
public ServerObject(ServerCompositor compositor) : base(compositor)
{
}
public void Activate()
{
_activationCount++;
if (_activationCount == 1)
Activated();
}
public void Deactivate()
{
#if DEBUG
if (_activationCount == 0)
throw new InvalidOperationException();
#endif
_activationCount--;
if (_activationCount == 0)
Deactivated();
}
private void Activated() => _animations?.Activated();
private void Deactivated() => _animations?.Deactivated();
protected new void SetValue(CompositionProperty prop, ref T field, T value)
{
field = value;
_animations?.OnSetDirectValue(prop);
}
protected void SetAnimatedValue(CompositionProperty prop, ref T field,
TimeSpan committedAt, IAnimationInstance animation) where T : struct
{
GetOrCreateAnimations().OnSetAnimatedValue(prop, ref field, committedAt, animation);
}
protected void SetAnimatedValue(CompositionProperty property, out T field, T value)
{
field = value;
_animations?.RemoveAnimationForProperty(property);
}
public virtual void NotifyAnimatedValueChanged(CompositionProperty property) => ValuesInvalidated();
public virtual CompositionProperty? GetCompositionProperty(string fieldName) => null;
ExpressionVariant IExpressionObject.GetProperty(string name)
{
if (_animations == null)
return CompositionProperty.Find(this.GetType(), name)?.GetVariant?.Invoke(this) ?? default;
return _animations.GetPropertyForAnimation(name);
}
}
}