Files
speckle-sharp-connectors/DUI3/Speckle.Connectors.DUI/Bridge/IdleCallManager.cs
T
Jedd Morgan f4d77bf8ce Top Level Exception Handler and Bindings fix (#76)
* TopLeveExceptionHandlerBindings

* Fixed idle manager on exceptional path

* null bindings check

* Made TopLevelExceptionHandler injectable

* Revit now works

* Fixed Tests

* returned unintentional change
2024-07-27 12:40:21 +01:00

72 lines
1.8 KiB
C#

using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
namespace Speckle.Connectors.DUI.Bridge;
public interface IIdleCallManager
{
void SubscribeToIdle(string id, Action action, Action addEvent);
void AppOnIdle(Action removeEvent);
}
//should be registered as singleton
[SuppressMessage("ReSharper", "InconsistentlySynchronizedField")]
public class IdleCallManager : IIdleCallManager
{
public ConcurrentDictionary<string, Action> Calls { get; } = new();
private readonly object _lock = new();
public bool IdleSubscriptionCalled { get; private set; }
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
public IdleCallManager(ITopLevelExceptionHandler topLevelExceptionHandler)
{
_topLevelExceptionHandler = topLevelExceptionHandler;
}
public void SubscribeToIdle(string id, Action action, Action addEvent) =>
_topLevelExceptionHandler.CatchUnhandled(() => SubscribeInternal(id, action, addEvent));
public void SubscribeInternal(string id, Action action, Action addEvent)
{
Calls.TryAdd(id, action);
if (!IdleSubscriptionCalled)
{
lock (_lock)
{
if (!IdleSubscriptionCalled)
{
addEvent.Invoke();
IdleSubscriptionCalled = true;
}
}
}
}
public void AppOnIdle(Action removeEvent) =>
_topLevelExceptionHandler.CatchUnhandled(() => AppOnIdleInternal(removeEvent));
public void AppOnIdleInternal(Action removeEvent)
{
foreach (KeyValuePair<string, Action> kvp in Calls)
{
_topLevelExceptionHandler.CatchUnhandled(() => kvp.Value.Invoke());
}
Calls.Clear();
if (IdleSubscriptionCalled)
{
lock (_lock)
{
if (IdleSubscriptionCalled)
{
removeEvent.Invoke();
IdleSubscriptionCalled = false;
}
}
}
}
}