forked from AvaloniaUI/Avalonia
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
556 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 105 additions & 5 deletions
110
src/Avalonia.Base/Rendering/Composition/Server/CompositionProperty.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,115 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
using Avalonia.Rendering.Composition.Expressions; | ||
|
||
namespace Avalonia.Rendering.Composition.Server; | ||
|
||
internal class CompositionProperty | ||
{ | ||
private static volatile int s_NextId = 1; | ||
public int Id { get; private set; } | ||
private static int s_nextId = 1; | ||
private static readonly object _lock = new(); | ||
|
||
public static CompositionProperty Register() => new() | ||
private static Dictionary<Type, List<CompositionProperty>> s_dynamicRegistry = new(); | ||
|
||
class ReadOnlyRegistry : Dictionary<Type, IReadOnlyDictionary<string, CompositionProperty>> | ||
{ | ||
|
||
} | ||
|
||
private static volatile ReadOnlyRegistry? s_ReadOnlyRegistry; | ||
|
||
public CompositionProperty(int id, string name, Type owner, Func<SimpleServerObject, ExpressionVariant>? getVariant) | ||
{ | ||
Id = id; | ||
Name = name; | ||
Owner = owner; | ||
GetVariant = getVariant; | ||
} | ||
|
||
public int Id { get; } | ||
public string Name { get; } | ||
public Type Owner { get; } | ||
public Func<SimpleServerObject, ExpressionVariant>? GetVariant { get; } | ||
|
||
public static CompositionProperty<TField> Register<TOwner, TField>(string name, Func<SimpleServerObject, TField> getField, Action<SimpleServerObject, TField> setField, | ||
Func<SimpleServerObject, ExpressionVariant>? getVariant) | ||
{ | ||
CompositionProperty<TField> prop; | ||
lock (_lock) | ||
{ | ||
var id = s_nextId++; | ||
prop = new CompositionProperty<TField>(id, name, typeof(TOwner), getField, setField, getVariant); | ||
} | ||
|
||
s_ReadOnlyRegistry = null; | ||
return prop; | ||
} | ||
|
||
static void PopulatePropertiesForType(Type type, List<CompositionProperty> l) | ||
{ | ||
Id = Interlocked.Increment(ref s_NextId) | ||
}; | ||
Type? t = type; | ||
while (t != null && t != typeof(object)) | ||
{ | ||
if (s_dynamicRegistry.TryGetValue(t, out var lst)) | ||
l.AddRange(lst); | ||
t = t.BaseType; | ||
} | ||
} | ||
|
||
static ReadOnlyRegistry Build() | ||
{ | ||
var reg = new ReadOnlyRegistry(); | ||
foreach (var type in s_dynamicRegistry.Keys) | ||
{ | ||
var lst = new List<CompositionProperty>(); | ||
PopulatePropertiesForType(type, lst); | ||
reg[type] = lst.ToDictionary(x => x.Name); | ||
} | ||
|
||
return reg; | ||
} | ||
|
||
public static IReadOnlyDictionary<string, CompositionProperty>? TryGetPropertiesForType(Type t) | ||
{ | ||
GetRegistry().TryGetValue(t, out var rv); | ||
return rv; | ||
} | ||
|
||
public static CompositionProperty? Find(Type owner, string name) | ||
{ | ||
if (TryGetPropertiesForType(owner)?.TryGetValue(name, out var prop) == true) | ||
return prop; | ||
return null; | ||
} | ||
|
||
static ReadOnlyRegistry GetRegistry() | ||
{ | ||
var reg = s_ReadOnlyRegistry; | ||
if (reg != null) | ||
return reg; | ||
lock (_lock) | ||
{ | ||
// ReSharper disable once NonAtomicCompoundOperator | ||
// This is the only line ever that would set the field to a not-null value, and we are inside of a lock | ||
return s_ReadOnlyRegistry ??= Build(); | ||
} | ||
} | ||
} | ||
|
||
internal class CompositionProperty<T> : CompositionProperty | ||
{ | ||
public Func<SimpleServerObject, T> GetField { get; } | ||
public Action<SimpleServerObject, T> SetField { get; } | ||
|
||
public CompositionProperty(int id, string name, Type owner, | ||
Func<SimpleServerObject, T> getField, | ||
Action<SimpleServerObject, T> setField, | ||
Func<SimpleServerObject, ExpressionVariant>? getVariant) | ||
: base(id, name, owner, getVariant) | ||
{ | ||
GetField = getField; | ||
SetField = setField; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositorAnimations.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Avalonia.Rendering.Composition.Server; | ||
|
||
internal class ServerCompositorAnimations | ||
{ | ||
private readonly HashSet<IServerClockItem> _clockItems = new(); | ||
private readonly List<IServerClockItem> _clockItemsToUpdate = new(); | ||
private readonly HashSet<ServerObjectAnimations> _dirtyAnimatedObjects = new(); | ||
private readonly Queue<ServerObjectAnimations> _dirtyAnimatedObjectQueue = new(); | ||
|
||
public void AddToClock(IServerClockItem item) => | ||
_clockItems.Add(item); | ||
|
||
public void RemoveFromClock(IServerClockItem item) => | ||
_clockItems.Remove(item); | ||
|
||
public void Process() | ||
{ | ||
foreach (var animation in _clockItems) | ||
_clockItemsToUpdate.Add(animation); | ||
|
||
foreach (var animation in _clockItemsToUpdate) | ||
animation.OnTick(); | ||
|
||
_clockItemsToUpdate.Clear(); | ||
|
||
while (_dirtyAnimatedObjectQueue.Count > 0) | ||
_dirtyAnimatedObjectQueue.Dequeue().EvaluateAnimations(); | ||
_dirtyAnimatedObjects.Clear(); | ||
} | ||
|
||
public void AddDirtyAnimatedObject(ServerObjectAnimations obj) | ||
{ | ||
if (_dirtyAnimatedObjects.Add(obj)) | ||
_dirtyAnimatedObjectQueue.Enqueue(obj); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.