From e5a1f62ccf5c34d5eeabb81558becec6a9e14c50 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Thu, 28 Nov 2024 19:39:36 +0000 Subject: [PATCH 1/7] feat: wip invalidates objects whose materials have changed --- .../Bindings/RhinoSendBinding.cs | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs index 2e6c263c5..0e79e2040 100644 --- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs +++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs @@ -4,6 +4,7 @@ using Rhino; using Rhino.Commands; using Rhino.DocObjects; +using Rhino.DocObjects.Tables; using Speckle.Connectors.Common.Caching; using Speckle.Connectors.Common.Cancellation; using Speckle.Connectors.Common.Operations; @@ -49,6 +50,7 @@ public sealed class RhinoSendBinding : ISendBinding /// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework /// private ConcurrentDictionary ChangedObjectIds { get; set; } = new(); + private ConcurrentDictionary ChangedMaterialIndexes { get; set; } = new(); private UnitSystem PreviousUnitSystem { get; set; } @@ -152,6 +154,15 @@ private void SubscribeToRhinoEvents() } }); + RhinoDoc.MaterialTableEvent += (_, args) => + { + if (args.EventType == MaterialTableEventType.Modified) + { + ChangedMaterialIndexes[args.Index] = 1; + _idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks); + } + }; + RhinoDoc.ModifyObjectAttributes += (_, e) => _topLevelExceptionHandler.CatchUnhandled(() => { @@ -266,11 +277,21 @@ private async Task RunExpirationChecks() _logger.LogError("Rhino expiration checks were running without an active doc."); return; } - var senders = _store.GetSenders(); - string[] objectIdsList = ChangedObjectIds.Keys.ToArray(); // NOTE: could not copy to array happens here - List expiredSenderIds = new(); + // Invalidate any objects whose materials have changed + var changedMaterialIndexes = ChangedMaterialIndexes.Keys.ToArray(); + foreach (var rhinoObject in RhinoDoc.ActiveDoc.Objects) + { + if (changedMaterialIndexes.Contains(rhinoObject.Attributes.MaterialIndex)) + { + ChangedObjectIds[rhinoObject.Id.ToString()] = 1; + } + } + + string[] objectIdsList = ChangedObjectIds.Keys.ToArray(); // NOTE: could not copy to array happens here _sendConversionCache.EvictObjects(objectIdsList); + var senders = _store.GetSenders(); + List expiredSenderIds = new(); foreach (SenderModelCard modelCard in senders) { From 474b9eb364e7ec06bb19e7be0f41aca37f084538 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Thu, 28 Nov 2024 20:10:22 +0000 Subject: [PATCH 2/7] feat: closes off cnx-855 wraps event in topLevelExceptionHandler and reinits changed material ids --- .../Bindings/RhinoSendBinding.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs index 0e79e2040..c2d78f01f 100644 --- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs +++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs @@ -155,13 +155,14 @@ private void SubscribeToRhinoEvents() }); RhinoDoc.MaterialTableEvent += (_, args) => - { - if (args.EventType == MaterialTableEventType.Modified) + _topLevelExceptionHandler.CatchUnhandled(() => { - ChangedMaterialIndexes[args.Index] = 1; - _idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks); - } - }; + if (args.EventType == MaterialTableEventType.Modified) + { + ChangedMaterialIndexes[args.Index] = 1; + _idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks); + } + }); RhinoDoc.ModifyObjectAttributes += (_, e) => _topLevelExceptionHandler.CatchUnhandled(() => @@ -305,6 +306,7 @@ private async Task RunExpirationChecks() await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false); ChangedObjectIds = new(); + ChangedMaterialIndexes = new(); } private async Task InvalidateAllSender() From 262062464edd40a6abe7b4281d1dfebc4116cf7c Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Thu, 28 Nov 2024 20:11:47 +0000 Subject: [PATCH 3/7] chore: comments --- .../Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs index c2d78f01f..4a55b0da8 100644 --- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs +++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs @@ -154,6 +154,7 @@ private void SubscribeToRhinoEvents() } }); + // Catches and stores changed material ids. These are then used in the expiry checks to invalidate all objects that have assigned any of those material ids. RhinoDoc.MaterialTableEvent += (_, args) => _topLevelExceptionHandler.CatchUnhandled(() => { @@ -289,6 +290,7 @@ private async Task RunExpirationChecks() } } + // Actual model card invalidation string[] objectIdsList = ChangedObjectIds.Keys.ToArray(); // NOTE: could not copy to array happens here _sendConversionCache.EvictObjects(objectIdsList); var senders = _store.GetSenders(); From 7639259c434de07ab54fa985606465b7f2d6fabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuzhan=20Koral?= <45078678+oguzhankoral@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:49:49 +0300 Subject: [PATCH 4/7] Clear token after every operation to prevent annoying message (#422) --- .../Bindings/RevitReceiveBinding.cs | 5 +++++ .../Bindings/RevitSendBinding.cs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs b/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs index 27bb4868a..2abd95945 100644 --- a/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs +++ b/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs @@ -102,5 +102,10 @@ await Commands _logger.LogModelCardHandledError(ex); await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false); } + finally + { + // otherwise the id of the operation persists on the cancellation manager and triggers 'Operations cancelled because of document swap!' message to UI. + _cancellationManager.CancelOperation(modelCardId); + } } } diff --git a/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitSendBinding.cs b/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitSendBinding.cs index f4c724515..818542eea 100644 --- a/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitSendBinding.cs +++ b/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitSendBinding.cs @@ -167,6 +167,11 @@ await Commands _logger.LogModelCardHandledError(ex); await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false); } + finally + { + // otherwise the id of the operation persists on the cancellation manager and triggers 'Operations cancelled because of document swap!' message to UI. + _cancellationManager.CancelOperation(modelCardId); + } } private async Task> RefreshElementsOnSender(SenderModelCard modelCard) From 92a8cf1510148852af7767debdacaca9ff80424c Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Fri, 29 Nov 2024 08:56:40 +0000 Subject: [PATCH 5/7] fix: performs expiration checks if actually any materials/objects have changed --- .../Bindings/RhinoSendBinding.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs index 4a55b0da8..23bf041ff 100644 --- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs +++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Bindings/RhinoSendBinding.cs @@ -281,15 +281,23 @@ private async Task RunExpirationChecks() } // Invalidate any objects whose materials have changed - var changedMaterialIndexes = ChangedMaterialIndexes.Keys.ToArray(); - foreach (var rhinoObject in RhinoDoc.ActiveDoc.Objects) + if (!ChangedMaterialIndexes.IsEmpty) { - if (changedMaterialIndexes.Contains(rhinoObject.Attributes.MaterialIndex)) + var changedMaterialIndexes = ChangedMaterialIndexes.Keys.ToArray(); + foreach (var rhinoObject in RhinoDoc.ActiveDoc.Objects) { - ChangedObjectIds[rhinoObject.Id.ToString()] = 1; + if (changedMaterialIndexes.Contains(rhinoObject.Attributes.MaterialIndex)) + { + ChangedObjectIds[rhinoObject.Id.ToString()] = 1; + } } } + if (ChangedObjectIds.IsEmpty) + { + return; + } + // Actual model card invalidation string[] objectIdsList = ChangedObjectIds.Keys.ToArray(); // NOTE: could not copy to array happens here _sendConversionCache.EvictObjects(objectIdsList); From 2e41d15f0db023fad04004aa8d31e39680594613 Mon Sep 17 00:00:00 2001 From: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:57:39 +0000 Subject: [PATCH 6/7] top level exception handler give a better exception when toasts fail (#423) --- .../Bridge/TopLevelExceptionHandler.cs | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/DUI3/Speckle.Connectors.DUI/Bridge/TopLevelExceptionHandler.cs b/DUI3/Speckle.Connectors.DUI/Bridge/TopLevelExceptionHandler.cs index a39ff0bc2..b8b78ee97 100644 --- a/DUI3/Speckle.Connectors.DUI/Bridge/TopLevelExceptionHandler.cs +++ b/DUI3/Speckle.Connectors.DUI/Bridge/TopLevelExceptionHandler.cs @@ -79,14 +79,7 @@ public async Task> CatchUnhandledAsync(Func> function) } catch (Exception ex) when (!ex.IsFatal()) { - _logger.LogError(ex, UNHANDLED_LOGGER_TEMPLATE); - await SetGlobalNotification( - ToastNotificationType.DANGER, - "Unhandled Exception Occured", - ex.ToFormattedString(), - false - ) - .ConfigureAwait(false); + await HandleException(ex).ConfigureAwait(false); return new(ex); } } @@ -97,6 +90,33 @@ await SetGlobalNotification( } } + private async Task HandleException(Exception ex) + { + _logger.LogError(ex, UNHANDLED_LOGGER_TEMPLATE); + + try + { + await SetGlobalNotification( + ToastNotificationType.DANGER, + "Unhandled Exception Occured", + ex.ToFormattedString(), + false + ) + .ConfigureAwait(false); + } + catch (Exception toastEx) + { + // Not only was a top level exception caught, but our attempt to display a toast failed! + // Toasts can fail if the BrowserBridge is not yet associated with a binding + // For this reason, binding authors should avoid doing anything in + // the constructors of bindings that may try and use the bridge! + AggregateException aggregateException = + new("An Unhandled top level exception was caught, and the toast failed to display it!", [toastEx, ex]); + + throw aggregateException; + } + } + /// /// Triggers an async action without explicitly needing to await it.
/// Any thrown by invoking will be handled by the
From 10055aa06ec3f5862d12ca21d7f935f5c4498bdf Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 2 Dec 2024 15:52:33 +0000 Subject: [PATCH 7/7] Fix for Autocad receive speed (#424) * update UI only every 50 times * Fix up browser to fire and forget * Autocad doesn't need to be async. Fixed up Rhino * Always invoke --- .../HostApp/AutocadColorBaker.cs | 7 +-- .../HostApp/AutocadInstanceBaker.cs | 3 +- .../HostApp/AutocadMaterialBaker.cs | 3 +- .../Receive/AutocadHostObjectBuilder.cs | 35 ++++++------ .../HostApp/RhinoInstanceBaker.cs | 3 +- .../Receive/RhinoHostObjectBuilder.cs | 13 +++-- .../DUI3ControlWebView.xaml.cs | 53 +++---------------- .../Instances/IInstanceBaker.cs | 2 +- 8 files changed, 41 insertions(+), 78 deletions(-) diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadColorBaker.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadColorBaker.cs index 531ded14e..7395ab6e8 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadColorBaker.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadColorBaker.cs @@ -29,10 +29,7 @@ public AutocadColorBaker(ILogger logger) ///
/// /// - public async Task ParseColors( - IReadOnlyCollection colorProxies, - IProgress onOperationProgressed - ) + public void ParseColors(IReadOnlyCollection colorProxies, IProgress onOperationProgressed) { var count = 0; foreach (ColorProxy colorProxy in colorProxies) @@ -64,8 +61,6 @@ IProgress onOperationProgressed { _logger.LogError(ex, "Failed parsing color proxy"); } - - await Task.Yield(); } } diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceBaker.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceBaker.cs index 35d44abe0..cf3439f7f 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceBaker.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceBaker.cs @@ -49,7 +49,7 @@ IConverterSettingsStore converterSettings } [SuppressMessage("Maintainability", "CA1506:Avoid excessive class coupling")] - public async Task BakeInstances( + public BakeResult BakeInstances( IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents, Dictionary> applicationIdMap, string baseLayerName, @@ -167,7 +167,6 @@ instanceOrDefinition is InstanceProxy instanceProxy } transaction.Commit(); - await Task.Yield(); return new(createdObjectIds, consumedObjectIds, conversionResults); } diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialBaker.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialBaker.cs index 4aea349fb..6afc37ebf 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialBaker.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialBaker.cs @@ -91,7 +91,7 @@ public void PurgeMaterials(string namePrefix) transaction.Commit(); } - public async Task ParseAndBakeRenderMaterials( + public void ParseAndBakeRenderMaterials( List materialProxies, string baseLayerPrefix, IProgress onOperationProgressed @@ -140,7 +140,6 @@ IProgress onOperationProgressed } transaction.Commit(); - await Task.Yield(); } private (ObjectId, ReceiveConversionResult) BakeMaterial( diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Receive/AutocadHostObjectBuilder.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Receive/AutocadHostObjectBuilder.cs index c9bdc4ee9..b2886a27d 100644 --- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Receive/AutocadHostObjectBuilder.cs +++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Receive/AutocadHostObjectBuilder.cs @@ -63,13 +63,15 @@ CancellationToken _ // NOTE: This is the only place we apply ISyncToThread across connectors. We need to sync up with main thread here // after GetObject and Deserialization. It is anti-pattern now. Happiness level 3/10 but works. return await _syncToThread - .RunOnThread( - async () => await BuildImpl(rootObject, projectName, modelName, onOperationProgressed).ConfigureAwait(false) - ) + .RunOnThread(async () => + { + await Task.CompletedTask.ConfigureAwait(true); + return BuildSync(rootObject, projectName, modelName, onOperationProgressed); + }) .ConfigureAwait(false); } - private async Task BuildImpl( + private HostObjectBuilderResult BuildSync( Base rootObject, string projectName, string modelName, @@ -108,14 +110,16 @@ IProgress onOperationProgressed // 3 - Bake materials and colors, as they are used later down the line by layers and objects if (unpackedRoot.RenderMaterialProxies != null) { - await _materialBaker - .ParseAndBakeRenderMaterials(unpackedRoot.RenderMaterialProxies, baseLayerPrefix, onOperationProgressed) - .ConfigureAwait(true); + _materialBaker.ParseAndBakeRenderMaterials( + unpackedRoot.RenderMaterialProxies, + baseLayerPrefix, + onOperationProgressed + ); } if (unpackedRoot.ColorProxies != null) { - await _colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed).ConfigureAwait(true); + _colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed); } // 5 - Convert atomic objects @@ -129,8 +133,7 @@ await _materialBaker onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count)); try { - List convertedObjects = await ConvertObject(atomicObject, layerPath, baseLayerPrefix) - .ConfigureAwait(true); + List convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix); applicationIdMap[objectId] = convertedObjects; @@ -152,9 +155,12 @@ await _materialBaker } // 6 - Convert instances - var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = await _instanceBaker - .BakeInstances(instanceComponentsWithPath, applicationIdMap, baseLayerPrefix, onOperationProgressed) - .ConfigureAwait(true); + var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances( + instanceComponentsWithPath, + applicationIdMap, + baseLayerPrefix, + onOperationProgressed + ); bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id)); bakedObjectIds.AddRange(createdInstanceIds); @@ -181,7 +187,7 @@ private void PreReceiveDeepClean(string baseLayerPrefix) _materialBaker.PurgeMaterials(baseLayerPrefix); } - private async Task> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix) + private List ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix) { string layerName = _layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix); var convertedEntities = new List(); @@ -204,7 +210,6 @@ private async Task> ConvertObject(Base obj, Collection[] layerPath, } tr.Commit(); - await Task.Delay(10).ConfigureAwait(true); return convertedEntities; } diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/HostApp/RhinoInstanceBaker.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/HostApp/RhinoInstanceBaker.cs index 8cc716e9f..cafc8ba5c 100644 --- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/HostApp/RhinoInstanceBaker.cs +++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/HostApp/RhinoInstanceBaker.cs @@ -42,7 +42,7 @@ ILogger logger /// Instance definitions and instances that need creating. /// A dict mapping { original application id -> [resulting application ids post conversion] } /// - public async Task BakeInstances( + public BakeResult BakeInstances( IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents, Dictionary> applicationIdMap, string baseLayerName, @@ -153,7 +153,6 @@ instanceOrDefinition is InstanceProxy instanceProxy } } - await Task.Yield(); return new(createdObjectIds, consumedObjectIds, conversionResults); } diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Receive/RhinoHostObjectBuilder.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Receive/RhinoHostObjectBuilder.cs index 3269efe44..56ca5de86 100644 --- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Receive/RhinoHostObjectBuilder.cs +++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Receive/RhinoHostObjectBuilder.cs @@ -55,7 +55,7 @@ ISdkActivityFactory activityFactory } #pragma warning disable CA1506 - public async Task Build( + public Task Build( #pragma warning restore CA1506 Base rootObject, string projectName, @@ -207,9 +207,12 @@ CancellationToken cancellationToken // 6 - Convert instances using (var _ = _activityFactory.Start("Converting instances")) { - var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = await _instanceBaker - .BakeInstances(instanceComponentsWithPath, applicationIdMap, baseLayerName, onOperationProgressed) - .ConfigureAwait(false); + var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances( + instanceComponentsWithPath, + applicationIdMap, + baseLayerName, + onOperationProgressed + ); bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id)); // remove all objects that have been "consumed" bakedObjectIds.AddRange(createdInstanceIds); // add instance ids @@ -224,7 +227,7 @@ CancellationToken cancellationToken } _converterSettings.Current.Document.Views.Redraw(); - return new HostObjectBuilderResult(bakedObjectIds, conversionResults); + return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, conversionResults)); } private void PreReceiveDeepClean(string baseLayerName) diff --git a/DUI3/Speckle.Connectors.DUI.WebView/DUI3ControlWebView.xaml.cs b/DUI3/Speckle.Connectors.DUI.WebView/DUI3ControlWebView.xaml.cs index 56ff2b85d..c401a3289 100644 --- a/DUI3/Speckle.Connectors.DUI.WebView/DUI3ControlWebView.xaml.cs +++ b/DUI3/Speckle.Connectors.DUI.WebView/DUI3ControlWebView.xaml.cs @@ -26,57 +26,20 @@ public DUI3ControlWebView(IServiceProvider serviceProvider) public object BrowserElement => Browser; - // { - // if (!Browser.IsInitialized) - // { - // throw new InvalidOperationException("Failed to execute script, Webview2 is not initialized yet."); - // } - // - // var t = Browser.Dispatcher.Invoke( - // async () => - // { - // var res = await Browser.ExecuteScriptAsync(script).ConfigureAwait(true); - // await Task.Delay(100).ConfigureAwait(true); - // return res; - // }, - // DispatcherPriority.Background - // ); - // - // _ = t.IsCompleted; - - // bool isAlreadyMainThread = Browser.Dispatcher.CheckAccess(); - // if (isAlreadyMainThread) - // { - // Browser.ExecuteScriptAsync(script); - // } - // else - // { - // Browser.Dispatcher.Invoke( - // () => - // { - // return Browser.ExecuteScriptAsync(script); - // }, - // DispatcherPriority.Background - // ); - // } - // } - - public async Task ExecuteScriptAsyncMethod(string script, CancellationToken cancellationToken) + public Task ExecuteScriptAsyncMethod(string script, CancellationToken cancellationToken) { if (!Browser.IsInitialized) { throw new InvalidOperationException("Failed to execute script, Webview2 is not initialized yet."); } - var callbackTask = await Browser - .Dispatcher.InvokeAsync( - async () => await Browser.ExecuteScriptAsync(script).ConfigureAwait(false), - DispatcherPriority.Background, - cancellationToken - ) - .Task.ConfigureAwait(false); - - _ = await callbackTask.ConfigureAwait(false); + //always invoke even on the main thread because it's better somehow + Browser.Dispatcher.Invoke( + //fire and forget + () => Browser.ExecuteScriptAsync(script), + DispatcherPriority.Background + ); + return Task.CompletedTask; } private void OnInitialized(object? sender, CoreWebView2InitializationCompletedEventArgs e) diff --git a/Sdk/Speckle.Connectors.Common/Instances/IInstanceBaker.cs b/Sdk/Speckle.Connectors.Common/Instances/IInstanceBaker.cs index fe6fa4af7..2ed88c836 100644 --- a/Sdk/Speckle.Connectors.Common/Instances/IInstanceBaker.cs +++ b/Sdk/Speckle.Connectors.Common/Instances/IInstanceBaker.cs @@ -14,7 +14,7 @@ public interface IInstanceBaker /// /// /// - Task BakeInstances( + BakeResult BakeInstances( IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents, Dictionary applicationIdMap, string baseLayerName,