Reputation: 599
I need to know how many non-persistent listeners were added to a UnityEvent.
It seems that there is no methods giving me this number in UnityEvent class. I can only get the persistent listeners count (the ones added from editor or with UnityEvent.AddPersistentListener() ). The only solution I have figured out is to create a child class and override the function with a count of registrations.
Here is a short code showing the problem :
private UnityEvent myEvent;
private void MyFunctionToHook()
{
// func logic
}
private void MyInitialisation()
{
myEvent.AddListener(MyFunctionToHook);
myEvent.AddListener(MyFunctionToHook);
myEvent.AddListener(MyFunctionToHook);
// here, I need to know how much hooks were added.
// ??
}
1) Do you have any ideas of how I can manage to track this information natively?
2) Am I doing this right ? Is it wrong wanting to know this information ?
It seems weird to not have access to this info, because it could be useful in unit-tests / warnings..etc
Thanks for your time.
Here is the unityEvent documentation : https://docs.unity3d.com/ScriptReference/Events.UnityEvent.html
[EDIT] the only solution I have found so far is the following :
public class TrackingUnityEvent<T0> : UnityEvent<T0>
{
private int nonPersistentListenersCount;
public int GetNonPersistentEventCount()
{
return nonPersistentListenersCount;
}
public void AddNonPersistantListener(UnityAction<T0> call)
{
AddListener(call);
nonPersistentListenersCount++;
}
public void RemoveNonPersistantListener(UnityAction<T0> call)
{
RemoveListener(call);
nonPersistentListenersCount--;
}
}
This way is gross because you can't tell if "RemoveListener()" and "AddListener()" are successfull as they are void.
Upvotes: 6
Views: 3681
Reputation: 240
I suggest a better approach using inheritance, overrides and thread safety. Note that [Serializable] is mandatory otherwise, the Editor GUI won't function properly. This approach is similar to your solution but overrides the base method, ensuring backward compatibility
[Serializable]
public class ExtendedUnityEvent<T> : UnityEvent<T>
{
private int listenerCount = 0;
public new void AddListener(UnityAction<T> call)
{
base.AddListener(call);
Interlocked.Increment(ref listenerCount);
}
public new void RemoveListener(UnityAction<T> call)
{
base.RemoveListener(call);
Interlocked.Decrement(ref listenerCount);
}
public int GetListenersCount()
{
return listenerCount + GetPersistentEventCount();
}
}
Upvotes: 1
Reputation: 134
Why don't you wrap the event inside another class without inheritance, so that you can count the listener? You can also add more code to the event...
public class MySpecialEvent {
private UnityEvent event;
public EventCount { get; private set; }
public void AddListener(UnityAction call) {
event.AddListener(call);
EventCount++;
}
public void RemoveListener(UnityAction call) {
event.RemoveListener(call);
EventCount--;
}
}
Upvotes: 0