Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NUI] Add WeakEventProxy class and improve invoke of WeakEvent #5424

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 47 additions & 5 deletions src/Tizen.NUI/src/internal/Common/WeakEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,33 @@ internal class WeakEvent<T>
{
private List<WeakHandler<T>> handlers = new List<WeakHandler<T>>();

public void Add(T handler)
protected int Count => handlers.Count;

public virtual void Add(T handler)
{
handlers.Add(new WeakHandler<T>(handler));
}

public void Remove(T handler)
public virtual void Remove(T handler)
{
handlers.RemoveAll(item => !item.IsAlive || item.Equals(handler));
}

public void Invoke(object sender, EventArgs args)
{
var copied = handlers.ToArray();
foreach (var item in copied)
var disposed = new HashSet<WeakHandler<T>>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 사용하면 바로 Dispose가 호출되나요?

Copy link
Collaborator Author

@rabbitfor rabbitfor Aug 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아뇨. 이 HashSet는 아래 foreach문을 돌때 IsAlive 가 false (이미 GC되어 reference에 닿을 수 없음을 뜻함)인 아이템들을 담기 위해 정의한 것이고 여기 담은 아이템들은 54라인에서 삭제합니다.


foreach (var item in handlers)
{
if (item.IsAlive)
{
item.Invoke(sender, args);
continue;
}
handlers.Remove(item);
disposed.Add(item);
}

handlers.RemoveAll(disposed.Contains);
}

internal class WeakHandler<U>
Expand Down Expand Up @@ -88,4 +93,41 @@ public void Invoke(params object[] args)
}
}
}

/// <summary>
/// Internal class that helps to make a proxy weak event connecting to a normal source event.
/// Note that the source event will have a strong reference of the WeakEventProxy instance instead of handler's.
/// Please replace it to WeakEventManager after version up.
/// </summary>
internal abstract class WeakEventProxy<EventArgsT> : WeakEvent<EventHandler<EventArgsT>>
{
protected abstract void ConnectToEvent(EventHandler<EventArgsT> handler);

protected abstract void DisconnectToEvent(EventHandler<EventArgsT> handler);

public override void Add(EventHandler<EventArgsT> handler)
{
if (Count == 0)
{
ConnectToEvent(OnEventInvoked);
}

base.Add(handler);
}

public override void Remove(EventHandler<EventArgsT> handler)
{
base.Remove(handler);

if (Count == 0)
{
DisconnectToEvent(OnEventInvoked);
}
}

private void OnEventInvoked(object sender, EventArgsT args)
{
Invoke(sender, args as EventArgs);
}
}
}
Loading