Browse Source

Apparently LayoutKind.Sequential is ignored for generic structs

pull/8105/head
Nikita Tsukanov 4 years ago
parent
commit
19f6f12fe4
  1. 7
      src/Avalonia.Base/Rendering/Composition/Animations/AnimatedValueStore.cs
  2. 8
      src/Avalonia.Base/Rendering/Composition/Server/ServerObject.cs
  3. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerVisual.cs
  4. 2
      src/tools/DevGenerators/CompositionGenerator/Generator.cs

7
src/Avalonia.Base/Rendering/Composition/Animations/AnimatedValueStore.cs

@ -32,11 +32,9 @@ namespace Avalonia.Rendering.Composition.Animations
/// The value store for non-animated values that can still be referenced by animations. /// The value store for non-animated values that can still be referenced by animations.
/// Simply stores the value and notifies subscribers /// Simply stores the value and notifies subscribers
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct ServerValueStore<T> internal struct ServerValueStore<T>
{ {
// HAS TO BE THE FIRST FIELD, accessed by field offset from ServerObject public ServerObjectSubscriptionStore Subscriptions;
private ServerObjectSubscriptionStore Subscriptions;
private T _value; private T _value;
public T Value public T Value
{ {
@ -61,8 +59,7 @@ namespace Avalonia.Rendering.Composition.Animations
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct ServerAnimatedValueStore<T> where T : struct internal struct ServerAnimatedValueStore<T> where T : struct
{ {
// HAS TO BE THE FIRST FIELD, accessed by field offset from ServerObject public ServerObjectSubscriptionStore Subscriptions;
private ServerObjectSubscriptionStore Subscriptions;
private IAnimationInstance? _animation; private IAnimationInstance? _animation;
private T _direct; private T _direct;
private T? _lastAnimated; private T? _lastAnimated;

8
src/Avalonia.Base/Rendering/Composition/Server/ServerObject.cs

@ -63,15 +63,15 @@ namespace Avalonia.Rendering.Composition.Server
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
protected int GetOffset<T>(ref T field) where T : struct protected int GetOffset(ref ServerObjectSubscriptionStore field)
{ {
return Unsafe.ByteOffset(ref Unsafe.As<uint, object>(ref _activationCount), return Unsafe.ByteOffset(ref _activationCount,
ref Unsafe.As<T, object>(ref field)) ref Unsafe.As<ServerObjectSubscriptionStore, uint>(ref field))
.ToInt32(); .ToInt32();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private ref ServerObjectSubscriptionStore GetStoreFromOffset(int offset) protected ref ServerObjectSubscriptionStore GetStoreFromOffset(int offset)
{ {
#if DEBUG #if DEBUG
if (offset == 0) if (offset == 0)

2
src/Avalonia.Base/Rendering/Composition/Server/ServerVisual.cs

@ -2,7 +2,9 @@ using System;
using System.Numerics; using System.Numerics;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Transport; using Avalonia.Rendering.Composition.Transport;
using Avalonia.Utilities;
namespace Avalonia.Rendering.Composition.Server namespace Avalonia.Rendering.Composition.Server
{ {

2
src/tools/DevGenerators/CompositionGenerator/Generator.cs

@ -298,7 +298,7 @@ namespace Avalonia.SourceGenerator.CompositionGenerator
AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(fieldOffsetName), AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(fieldOffsetName),
InvocationExpression(MemberAccess(IdentifierName(uninitializedObjectName), "GetOffset"), InvocationExpression(MemberAccess(IdentifierName(uninitializedObjectName), "GetOffset"),
ArgumentList(SingletonSeparatedList(Argument( ArgumentList(SingletonSeparatedList(Argument(
RefExpression(MemberAccess(IdentifierName(uninitializedObjectName), fieldName))))))))); RefExpression(MemberAccess(MemberAccess(IdentifierName(uninitializedObjectName), fieldName), "Subscriptions")))))))));
if (prop.DefaultValue != null) if (prop.DefaultValue != null)
{ {

Loading…
Cancel
Save