Skip to content

Commit

Permalink
perf(timeline): Remove the use of events and disposables
Browse files Browse the repository at this point in the history
Removes the use of events and disposable to reduce the memory footprint.
  • Loading branch information
jeromelaban committed Jan 18, 2022
1 parent 97d5328 commit 922bb4b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 37 deletions.
4 changes: 2 additions & 2 deletions src/Uno.UI/UI/Xaml/Media/Animation/ITimeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal interface ITimeline : IDisposable
void SeekAlignedToLastTick(TimeSpan offset);
void SkipToFill();
void Deactivate();
event EventHandler<object> Completed;
event EventHandler<object> Failed;
void RegisterListener(ITimelineListener storyboard);
void UnregisterListener(ITimelineListener storyboard);
}
}
8 changes: 8 additions & 0 deletions src/Uno.UI/UI/Xaml/Media/Animation/ITimelineListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Windows.UI.Xaml.Media.Animation
{
internal interface ITimelineListener
{
void ChildCompleted(Timeline timeline);
void ChildFailed(Timeline timeline);
}
}
34 changes: 5 additions & 29 deletions src/Uno.UI/UI/Xaml/Media/Animation/Storyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Windows.UI.Xaml.Media.Animation
{
[ContentProperty(Name = "Children")]
public sealed partial class Storyboard : Timeline, ITimeline, IAdditionalChildrenProvider, IThemeChangeAware
public sealed partial class Storyboard : Timeline, ITimeline, IAdditionalChildrenProvider, IThemeChangeAware, ITimelineListener
{
private static readonly IEventProvider _trace = Tracing.Get(TraceProvider.Id);
private EventActivity _traceActivity;
Expand All @@ -34,7 +34,6 @@ public static class TraceProvider
private int _replayCount = 1;
private int _runningChildren = 0;
private bool _hasFillingChildren = false;
private Dictionary<ITimeline, IDisposable> _childrenSubscriptions = new Dictionary<ITimeline, IDisposable>();

public Storyboard()
{
Expand Down Expand Up @@ -77,11 +76,7 @@ public Storyboard()
/// <param name="child"></param>
private void DisposeChildRegistrations(ITimeline child)
{
if(_childrenSubscriptions.TryGetValue(child, out var disposable))
{
disposable.Dispose();
_childrenSubscriptions.Remove(child);
}
child.UnregisterListener(this);
}

/// <summary>
Expand Down Expand Up @@ -127,16 +122,7 @@ private void Play()
DisposeChildRegistrations(child);

_runningChildren++;
child.Completed += Child_Completed;
child.Failed += Child_Failed;

_childrenSubscriptions.Add(
child,
Disposable.Create(() => {
child.Completed -= Child_Completed;
child.Failed -= Child_Failed;
})
);
child.RegisterListener(this);

child.Begin();
}
Expand Down Expand Up @@ -330,13 +316,8 @@ public TimeSpan GetCurrentTime()
throw new NotImplementedException();
}

private void Child_Failed(object sender, object e)
void ITimelineListener.ChildFailed(Timeline child)
{
if (!(sender is Timeline child))
{
return;
}

DisposeChildRegistrations(child);

Interlocked.Decrement(ref _runningChildren);
Expand All @@ -345,13 +326,8 @@ private void Child_Failed(object sender, object e)
// child, where completed relates to all children being completed.
}

private void Child_Completed(object sender, object e)
void ITimelineListener.ChildCompleted(Timeline child)
{
if (!(sender is Timeline child))
{
return;
}

DisposeChildRegistrations(child);

Interlocked.Decrement(ref _runningChildren);
Expand Down
27 changes: 21 additions & 6 deletions src/Uno.UI/UI/Xaml/Media/Animation/Timeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public partial class Timeline : DependencyObject, ITimeline
{
private WeakReference<DependencyObject> _targetElement;
private BindingPath _propertyInfo;
private List<ITimelineListener> _timelineListeners = new();

public Timeline()
{
Expand Down Expand Up @@ -87,16 +88,30 @@ public RepeatBehavior RepeatBehavior


public event EventHandler<object> Completed;
internal event EventHandler<object> Failed;

event EventHandler<object> ITimeline.Failed
void ITimeline.RegisterListener(ITimelineListener listener)
=> _timelineListeners.Add(listener);

void ITimeline.UnregisterListener(ITimelineListener listener)
=> _timelineListeners.Remove(listener);

protected void OnCompleted()
{
add => Failed += value;
remove => Failed += value;
Completed?.Invoke(this, null);

for (var i = 0; i < _timelineListeners.Count; i++)
{
_timelineListeners[i].ChildCompleted(this);
}
}

protected void OnCompleted() => Completed?.Invoke(this, null);
protected void OnFailed() => Failed?.Invoke(this, null);
protected void OnFailed()
{
for (var i = 0; i < _timelineListeners.Count; i++)
{
_timelineListeners[i].ChildFailed(this);
}
}

/// <summary>
/// Compute duration of the Timeline. Sometimes it's define by components.
Expand Down

0 comments on commit 922bb4b

Please sign in to comment.