Skip to content

Commit

Permalink
Introduce Event aggregator (#417)
Browse files Browse the repository at this point in the history
* Remove Dataflow usage

* format and remove dep

* merge fixes

* Fix serializer

* Add MainThreadContext

* add some main context detection

* add RevitMainThreadContext

* remove revit async?

* formatting

* use mainThreadContext

* Use more MainThreadContext

* some rearranging

* renaming

* Revit needs new run async

* merge fixes

* gather on worker, convert on main

* operations know threading but not host apps

* rhino options

* revit can receive

* autocad in progress

* need to yield for UI thread async

* revamp yield

* Found APIContext and removed it

* ArcGIS runs all workers on MCT thread

* Refactor ThreadContext and ArcGIS saving is always on a worker

* Revit threading is simplier?

* ArcGIS can not always go to the queued task

* format

* fix tekla compile errors

* Use EventAggregator to decouple exception handler and UI

* it's ALIVE

* regenerate locks

* Add Prism Evening to DUI

* clean up

* always run on background thread

* Clean up to be specific

* update etabs

* thread context

* autocad threading?

* merge fixes

* remove more async

* clean up

* fix build issues

* Do top level handling in event aggregator

* add some rhino events

* add more Rhino events and do Idle as OneTime with Id

* fix up rhino idle usages

* fmt

* can build agian

* Use valuetask

* fmt

* fix up some bridge execution to be sync

* cleanup

* add some non async paths for progress

* format

* remove needless selection

* Fixes

* Convert tekla

* selection event is used without idle

* Build fixes from merge

* Fix tests and clean up

* Add new events

* Properly dispose one time events

* Minor tekla updates
  • Loading branch information
adamhathcock authored Jan 21, 2025
1 parent 00669ea commit 83efebf
Show file tree
Hide file tree
Showing 74 changed files with 1,315 additions and 414 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ public class ArcGISSelectionBinding : ISelectionBinding
public string Name => "selectionBinding";
public IBrowserBridge Parent { get; }

public ArcGISSelectionBinding(IBrowserBridge parent, MapMembersUtils mapMemberUtils)
public ArcGISSelectionBinding(
IBrowserBridge parent,
MapMembersUtils mapMemberUtils,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_mapMemberUtils = mapMemberUtils;
Parent = parent;
var topLevelHandler = parent.TopLevelExceptionHandler;

// example: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Map-Authoring/QueryBuilderControl/DefinitionQueryDockPaneViewModel.cs
// MapViewEventArgs args = new(MapView.Active);
TOCSelectionChangedEvent.Subscribe(_ => topLevelHandler.CatchUnhandled(OnSelectionChanged), true);
TOCSelectionChangedEvent.Subscribe(_ => topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged), true);
}

private void OnSelectionChanged()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
Expand Down Expand Up @@ -69,7 +70,9 @@ public ArcGISSendBinding(
ILogger<ArcGISSendBinding> logger,
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
MapMembersUtils mapMemberUtils,
IThreadContext threadContext
IThreadContext threadContext,
IEventAggregator eventAggregator,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_store = store;
Expand All @@ -79,18 +82,20 @@ IThreadContext threadContext
_sendConversionCache = sendConversionCache;
_operationProgressManager = operationProgressManager;
_logger = logger;
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
_topLevelExceptionHandler = topLevelExceptionHandler;
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
_mapMemberUtils = mapMemberUtils;
_threadContext = threadContext;

Parent = parent;
Commands = new SendBindingUICommands(parent);
SubscribeToArcGISEvents();
_store.DocumentChanged += (_, _) =>
{
_sendConversionCache.ClearCache();
};
eventAggregator
.GetEvent<DocumentChangedEvent>()
.Subscribe(_ =>
{
_sendConversionCache.ClearCache();
});
}

private void SubscribeToArcGISEvents()
Expand Down Expand Up @@ -201,23 +206,23 @@ private void SubscribeToAnyDataSourceChange(Table layerTable)
{
RowCreatedEvent.Subscribe(
(args) =>
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await OnRowChanged(args);
}),
layerTable
);
RowChangedEvent.Subscribe(
(args) =>
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await OnRowChanged(args);
}),
layerTable
);
RowDeletedEvent.Subscribe(
(args) =>
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
_topLevelExceptionHandler.FireAndForget(async () =>
{
await OnRowChanged(args);
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Speckle.Connectors.ArcGIS.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
Expand All @@ -21,18 +22,21 @@ public class BasicConnectorBinding : IBasicConnectorBinding
private readonly DocumentModelStore _store;
private readonly ISpeckleApplication _speckleApplication;

public BasicConnectorBinding(DocumentModelStore store, IBrowserBridge parent, ISpeckleApplication speckleApplication)
public BasicConnectorBinding(
DocumentModelStore store,
IBrowserBridge parent,
ISpeckleApplication speckleApplication,
IEventAggregator eventAggregator
)
{
_store = store;
_speckleApplication = speckleApplication;
Parent = parent;
Commands = new BasicConnectorBindingCommands(parent);

_store.DocumentChanged += (_, _) =>
parent.TopLevelExceptionHandler.FireAndForget(async () =>
{
await Commands.NotifyDocumentChanged();
});
eventAggregator
.GetEvent<DocumentChangedEvent>()
.Subscribe(async _ => await Commands.NotifyDocumentChanged().ConfigureAwait(false));
}

public string GetSourceApplicationName() => _speckleApplication.Slug;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public static void AddArcGIS(this IServiceCollection serviceCollection)
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
serviceCollection.AddSingleton<IBasicConnectorBinding, BasicConnectorBinding>();

serviceCollection.RegisterTopLevelExceptionHandler();
serviceCollection.AddSingleton(DefaultTraversal.CreateTraversalFunc());

// register send operation and dependencies
Expand Down
2 changes: 2 additions & 0 deletions Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/SpeckleModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.ArcGIS.DependencyInjection;
using Speckle.Connectors.Common;
using Speckle.Connectors.DUI;
using Speckle.Converters.ArcGIS3;
using Speckle.Sdk.Host;
using Module = ArcGIS.Desktop.Framework.Contracts.Module;
Expand Down Expand Up @@ -34,6 +35,7 @@ public SpeckleModule()
services.AddArcGIS();
services.AddArcGISConverters();
Container = services.BuildServiceProvider();
Container.UseDUI();
}

private HostAppVersion GetVersion()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Speckle.Connectors.Common.Threading;

namespace Speckle.Connectors.ArcGIS.Utils;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using ArcGIS.Desktop.Mapping.Events;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;

Expand All @@ -12,15 +13,18 @@ namespace Speckle.Connectors.ArcGIS.Utils;
public class ArcGISDocumentStore : DocumentModelStore
{
private readonly IThreadContext _threadContext;
private readonly IEventAggregator _eventAggregator;

public ArcGISDocumentStore(
IJsonSerializer jsonSerializer,
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext
IThreadContext threadContext,
IEventAggregator eventAggregator
)
: base(jsonSerializer)
{
_threadContext = threadContext;
_eventAggregator = eventAggregator;
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
ProjectSavingEvent.Subscribe(
_ =>
Expand All @@ -38,13 +42,16 @@ IThreadContext threadContext
},
true
);
}

public override async Task OnDocumentStoreInitialized()
{
// in case plugin was loaded into already opened Map, read metadata from the current Map
if (!IsDocumentInit && MapView.Active != null)
{
IsDocumentInit = true;
LoadState();
OnDocumentChanged();
await _eventAggregator.GetEvent<DocumentChangedEvent>().PublishAsync(new object());
}
}

Expand All @@ -69,7 +76,7 @@ private void OnProjectSaving()
/// <summary>
/// On map view switch, this event trigger twice, first for outgoing view, second for incoming view.
/// </summary>
private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
private async void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
{
if (args.IncomingView is null)
{
Expand All @@ -78,7 +85,7 @@ private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)

IsDocumentInit = true;
LoadState();
OnDocumentChanged();
await _eventAggregator.GetEvent<DocumentChangedEvent>().PublishAsync(new object());
}

protected override void HostAppSaveState(string modelCardState) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Sdk;
Expand Down Expand Up @@ -31,6 +32,7 @@ public AutocadBasicConnectorBinding(
IAccountManager accountManager,
ISpeckleApplication speckleApplication,
ILogger<AutocadBasicConnectorBinding> logger,
IEventAggregator eventAggregator,
IThreadContext threadContext
)
{
Expand All @@ -39,8 +41,9 @@ IThreadContext threadContext
_accountManager = accountManager;
_speckleApplication = speckleApplication;
Commands = new BasicConnectorBindingCommands(parent);
_store.DocumentChanged += (_, _) =>
parent.TopLevelExceptionHandler.FireAndForget(async () =>
eventAggregator
.GetEvent<DocumentChangedEvent>()
.Subscribe(async _ =>
{
await Commands.NotifyDocumentChanged();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ public class AutocadSelectionBinding : ISelectionBinding

public IBrowserBridge Parent { get; }

public AutocadSelectionBinding(IBrowserBridge parent, IThreadContext threadContext)
public AutocadSelectionBinding(
IBrowserBridge parent,
IThreadContext threadContext,
ITopLevelExceptionHandler topLevelExceptionHandler
)
{
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
_topLevelExceptionHandler = topLevelExceptionHandler;
Parent = parent;
_threadContext = threadContext;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Concurrent;
using Autodesk.AutoCAD.DatabaseServices;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
Expand All @@ -11,6 +11,7 @@
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Exceptions;
using Speckle.Connectors.DUI.Logging;
using Speckle.Connectors.DUI.Models;
Expand Down Expand Up @@ -60,7 +61,9 @@ protected AutocadSendBaseBinding(
IOperationProgressManager operationProgressManager,
ILogger<AutocadSendBinding> logger,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext,
IEventAggregator eventAggregator
)
{
_store = store;
Expand All @@ -73,7 +76,7 @@ IThreadContext threadContext
_logger = logger;
_speckleApplication = speckleApplication;
_threadContext = threadContext;
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
_topLevelExceptionHandler = topLevelExceptionHandler;
Parent = parent;
Commands = new SendBindingUICommands(parent);

Expand All @@ -86,10 +89,8 @@ IThreadContext threadContext
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
}
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
_store.DocumentChanged += (_, _) =>
{
_sendConversionCache.ClearCache();
};

eventAggregator.GetEvent<DocumentChangedEvent>().Subscribe(_ => _sendConversionCache.ClearCache());
}

private readonly List<string> _docSubsTracker = new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Models.Card.SendFilter;
using Speckle.Converters.Autocad;
Expand All @@ -30,7 +31,9 @@ public AutocadSendBinding(
ILogger<AutocadSendBinding> logger,
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
ISpeckleApplication speckleApplication,
IThreadContext threadContext
ITopLevelExceptionHandler topLevelExceptionHandler,
IThreadContext threadContext,
IEventAggregator eventAggregator
)
: base(
store,
Expand All @@ -43,7 +46,9 @@ IThreadContext threadContext
operationProgressManager,
logger,
speckleApplication,
threadContext
topLevelExceptionHandler,
threadContext,
eventAggregator
)
{
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ public static void AddAutocadBase(this IServiceCollection serviceCollection)
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
serviceCollection.AddSingleton<IBasicConnectorBinding, AutocadBasicConnectorBinding>();
serviceCollection.AddSingleton<IBinding, ConfigBinding>();

serviceCollection.RegisterTopLevelExceptionHandler();
}

public static void LoadSend(this IServiceCollection serviceCollection)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Eventing;
using Speckle.Connectors.DUI.Models;
using Speckle.Connectors.DUI.Utils;

Expand All @@ -9,15 +10,18 @@ public class AutocadDocumentStore : DocumentModelStore
private readonly string _nullDocumentName = "Null Doc";
private string _previousDocName;
private readonly AutocadDocumentManager _autocadDocumentManager;
private readonly IEventAggregator _eventAggregator;

public AutocadDocumentStore(
IJsonSerializer jsonSerializer,
AutocadDocumentManager autocadDocumentManager,
ITopLevelExceptionHandler topLevelExceptionHandler
ITopLevelExceptionHandler topLevelExceptionHandler,
IEventAggregator eventAggregator
)
: base(jsonSerializer)
{
_autocadDocumentManager = autocadDocumentManager;
_eventAggregator = eventAggregator;
_previousDocName = _nullDocumentName;

// POC: Will be addressed to move it into AutocadContext!
Expand All @@ -38,7 +42,7 @@ ITopLevelExceptionHandler topLevelExceptionHandler
// OnDocChangeInternal((Document)args.DocumentWindow.Document);
}

private void OnDocChangeInternal(Document? doc)
private async void OnDocChangeInternal(Document? doc)
{
var currentDocName = doc != null ? doc.Name : _nullDocumentName;
if (_previousDocName == currentDocName)
Expand All @@ -48,7 +52,7 @@ private void OnDocChangeInternal(Document? doc)

_previousDocName = currentDocName;
LoadState();
OnDocumentChanged();
await _eventAggregator.GetEvent<DocumentChangedEvent>().PublishAsync(new object());
}

protected override void LoadState()
Expand Down
Loading

0 comments on commit 83efebf

Please sign in to comment.